001package io.ebean; 002 003import io.ebean.annotation.TxIsolation; 004import io.ebean.cache.ServerCacheManager; 005import io.ebean.plugin.Property; 006import io.ebean.text.csv.CsvReader; 007import io.ebean.text.json.JsonContext; 008 009import javax.annotation.Nonnull; 010import javax.annotation.Nullable; 011import javax.persistence.OptimisticLockException; 012import javax.persistence.PersistenceException; 013import java.util.Collection; 014import java.util.List; 015import java.util.Map; 016import java.util.Set; 017import java.util.concurrent.Callable; 018 019/** 020 * DB is a registry of {@link Database} by name. 021 * <p> 022 * DB additionally provides a convenient way to use the 'default' Database. 023 * <p> 024 * <h3>Default database</h3> 025 * <p> 026 * One of the Database instances can be registered as the "default database" 027 * and can be obtained using <code>DB.getDefault()</code> 028 * </p> 029 * <pre>{@code 030 * 031 * Database database = DB.getDefault(); 032 * 033 * }</pre> 034 * 035 * <h3>Named database</h3> 036 * <p> 037 * Multiple database instances can be registered with DB and we can obtain them 038 * using <code>DB.byName()</code> 039 * </p> 040 * <pre>{@code 041 * 042 * Database hrDatabase = DB.byName("hr"); 043 * 044 * }</pre> 045 * 046 * <h3>Convenience methods</h3> 047 * <p> 048 * DB has methods like {@link #find(Class)} and {@link #save(Object)} which are 049 * just convenience for using the default database. 050 * </p> 051 * 052 * <pre>{@code 053 * 054 * // fetch using the default database 055 * Order order = DB.find(Order.class, 10); 056 * 057 * // is the same as 058 * Database database = DB.getDefault(); 059 * Order order = database.find(Order.class, 10); 060 * 061 * }</pre> 062 */ 063public final class DB { 064 065 private static final DbContext context = DbContext.getInstance(); 066 067 /** 068 * Hide constructor. 069 */ 070 private DB() { 071 } 072 073 /** 074 * Backdoor for registering a mock implementation of Database as the default database. 075 */ 076 protected static Database mock(String name, Database server, boolean defaultServer) { 077 return context.mock(name, server, defaultServer); 078 } 079 080 /** 081 * Return the default database. 082 */ 083 public static Database getDefault() { 084 return context.getDefault(); 085 } 086 087 /** 088 * Return the database for the given name. 089 * 090 * @param name The name of the database 091 */ 092 public static Database byName(String name) { 093 return context.get(name); 094 } 095 096 /** 097 * Return the ScriptRunner for the default database. 098 * <p> 099 * Useful to run SQL scripts that are resources. For example a test script 100 * for inserting seed data for a particular test. 101 * 102 * <pre>{@code 103 * 104 * DB.script().run("/scripts/test-script.sql") 105 * 106 * }</pre> 107 */ 108 public static ScriptRunner script() { 109 return getDefault().script(); 110 } 111 112 /** 113 * Return the ExpressionFactory from the default database. 114 * <p> 115 * The ExpressionFactory is used internally by the query and ExpressionList to 116 * build the WHERE and HAVING clauses. Alternatively you can use the 117 * ExpressionFactory directly to create expressions to add to the query where 118 * clause. 119 * </p> 120 * <p> 121 * Alternatively you can use the {@link Expr} as a shortcut to the 122 * ExpressionFactory of the 'Default' database. 123 * </p> 124 * <p> 125 * You generally need to the an ExpressionFactory (or {@link Expr}) to build 126 * an expression that uses OR like Expression e = Expr.or(..., ...); 127 * </p> 128 */ 129 public static ExpressionFactory getExpressionFactory() { 130 return getDefault().getExpressionFactory(); 131 } 132 133 /** 134 * Return the next identity value for a given bean type. 135 * <p> 136 * This will only work when a IdGenerator is on this bean type such as a DB 137 * sequence or UUID. 138 * </p> 139 * <p> 140 * For DB's supporting getGeneratedKeys and sequences such as Oracle10 you do 141 * not need to use this method generally. It is made available for more 142 * complex cases where it is useful to get an ID prior to some processing. 143 * </p> 144 */ 145 public static Object nextId(Class<?> beanType) { 146 return getDefault().nextId(beanType); 147 } 148 149 /** 150 * Start a transaction with 'REQUIRED' semantics. 151 * <p> 152 * With REQUIRED semantics if an active transaction already exists that transaction will be used. 153 * </p> 154 * <p> 155 * The transaction is stored in a ThreadLocal variable and typically you only 156 * need to use the returned Transaction <em>IF</em> you wish to do things like 157 * use batch mode, change the transaction isolation level, use savepoints or 158 * log comments to the transaction log. 159 * </p> 160 * <p> 161 * Example of using a transaction to span multiple calls to find(), save() 162 * etc. 163 * </p> 164 * <pre>{@code 165 * 166 * try (Transaction transaction = DB.beginTransaction()) { 167 * 168 * Order order = DB.find(Order.class, 42); 169 * order.setStatus(Status.COMPLETE); 170 * order.save(); 171 * 172 * transaction.commit(); 173 * } 174 * 175 * }</pre> 176 * <p> 177 * If we want to externalise the transaction management then we do this via Database. 178 * With Database we can pass the transaction to the various find(), save() and execute() 179 * methods. This gives us the ability to create the transactions externally from Ebean 180 * and use the transaction explicitly via the various methods available on Database. 181 * </p> 182 */ 183 public static Transaction beginTransaction() { 184 return getDefault().beginTransaction(); 185 } 186 187 /** 188 * Create a new transaction that is not held in TransactionThreadLocal. 189 * <p> 190 * You will want to do this if you want multiple Transactions in a single 191 * thread or generally use transactions outside of the TransactionThreadLocal 192 * management. 193 * </p> 194 */ 195 public static Transaction createTransaction() { 196 return getDefault().createTransaction(); 197 } 198 199 /** 200 * Start a transaction additionally specifying the isolation level. 201 * 202 * @param isolation the Transaction isolation level 203 */ 204 public static Transaction beginTransaction(TxIsolation isolation) { 205 return getDefault().beginTransaction(isolation); 206 } 207 208 /** 209 * Start a transaction typically specifying REQUIRES_NEW or REQUIRED semantics. 210 * <p> 211 * Note that this provides an try finally alternative to using {@link #executeCall(TxScope, Callable)} or 212 * {@link #execute(TxScope, Runnable)}. 213 * </p> 214 * <p> 215 * <h3>REQUIRES_NEW example:</h3> 216 * <pre>{@code 217 * // Start a new transaction. If there is a current transaction 218 * // suspend it until this transaction ends 219 * 220 * try (Transaction txn = DB.beginTransaction(TxScope.requiresNew())) { 221 * ... 222 * 223 * // commit the transaction 224 * txn.commit(); 225 * } 226 * }</pre> 227 * 228 * <h3>REQUIRED example:</h3> 229 * <pre>{@code 230 * // start a new transaction if there is not a current transaction 231 * 232 * try (Transaction txn = DB.beginTransaction(TxScope.required())) { 233 * ... 234 * 235 * // commit the transaction if it was created or 236 * // do nothing if there was already a current transaction 237 * txn.commit(); 238 * } 239 * }</pre> 240 */ 241 public static Transaction beginTransaction(TxScope scope) { 242 return getDefault().beginTransaction(scope); 243 } 244 245 /** 246 * Returns the current transaction or null if there is no current transaction in scope. 247 */ 248 public static Transaction currentTransaction() { 249 return getDefault().currentTransaction(); 250 } 251 252 /** 253 * The batch will be flushing automatically but you can use this to explicitly 254 * flush the batch if you like. 255 * <p> 256 * Flushing occurs automatically when: 257 * </p> 258 * <ul> 259 * <li>the batch size is reached</li> 260 * <li>A query is executed on the same transaction</li> 261 * <li>UpdateSql or CallableSql are mixed with bean save and delete</li> 262 * <li>Transaction commit occurs</li> 263 * <li>A getter method is called on a batched bean</li> 264 * </ul> 265 */ 266 public static void flush() { 267 currentTransaction().flush(); 268 } 269 270 /** 271 * Register a TransactionCallback on the currently active transaction. 272 * <p/> 273 * If there is no currently active transaction then a PersistenceException is thrown. 274 * 275 * @param transactionCallback the transaction callback to be registered with the current transaction 276 * @throws PersistenceException if there is no currently active transaction 277 */ 278 public static void register(TransactionCallback transactionCallback) throws PersistenceException { 279 getDefault().register(transactionCallback); 280 } 281 282 /** 283 * Commit the current transaction. 284 */ 285 public static void commitTransaction() { 286 getDefault().commitTransaction(); 287 } 288 289 /** 290 * Rollback the current transaction. 291 */ 292 public static void rollbackTransaction() { 293 getDefault().rollbackTransaction(); 294 } 295 296 /** 297 * If the current transaction has already been committed do nothing otherwise 298 * rollback the transaction. 299 * <p> 300 * It is preferable to use <em>try with resources</em> rather than this. 301 * </p> 302 * <p> 303 * Useful to put in a finally block to ensure the transaction is ended, rather 304 * than a rollbackTransaction() in each catch block. 305 * </p> 306 * <p> 307 * Code example: 308 * </p> 309 * <pre>{@code 310 * DB.beginTransaction(); 311 * try { 312 * // do some fetching and or persisting 313 * 314 * // commit at the end 315 * DB.commitTransaction(); 316 * 317 * } finally { 318 * // if commit didn't occur then rollback the transaction 319 * DB.endTransaction(); 320 * } 321 * }</pre> 322 */ 323 public static void endTransaction() { 324 getDefault().endTransaction(); 325 } 326 327 /** 328 * Mark the current transaction as rollback only. 329 */ 330 public static void setRollbackOnly() { 331 getDefault().currentTransaction().setRollbackOnly(); 332 } 333 334 /** 335 * Return a map of the differences between two objects of the same type. 336 * <p> 337 * When null is passed in for b, then the 'OldValues' of a is used for the 338 * difference comparison. 339 * </p> 340 */ 341 public static Map<String, ValuePair> diff(Object a, Object b) { 342 return getDefault().diff(a, b); 343 } 344 345 /** 346 * Either Insert or Update the bean depending on its state. 347 * <p> 348 * If there is no current transaction one will be created and committed for 349 * you automatically. 350 * </p> 351 * <p> 352 * Save can cascade along relationships. For this to happen you need to 353 * specify a cascade of CascadeType.ALL or CascadeType.PERSIST on the 354 * OneToMany, OneToOne or ManyToMany annotation. 355 * </p> 356 * <p> 357 * When a save cascades via a OneToMany or ManyToMany Ebean will automatically 358 * set the 'parent' object to the 'detail' object. In the example below in 359 * saving the order and cascade saving the order details the 'parent' order 360 * will be set against each order detail when it is saved. 361 * </p> 362 */ 363 public static void save(Object bean) throws OptimisticLockException { 364 getDefault().save(bean); 365 } 366 367 /** 368 * Insert the bean. This is useful when you set the Id property on a bean and 369 * want to explicitly insert it. 370 */ 371 public static void insert(Object bean) { 372 getDefault().insert(bean); 373 } 374 375 /** 376 * Insert a collection of beans. 377 */ 378 public static void insertAll(Collection<?> beans) { 379 getDefault().insertAll(beans); 380 } 381 382 /** 383 * Marks the entity bean as dirty. 384 * <p> 385 * This is used so that when a bean that is otherwise unmodified is updated with the version 386 * property updated. 387 * <p> 388 * An unmodified bean that is saved or updated is normally skipped and this marks the bean as 389 * dirty so that it is not skipped. 390 * <pre>{@code 391 * 392 * Customer customer = DB.find(Customer, id); 393 * 394 * // mark the bean as dirty so that a save() or update() will 395 * // increment the version property 396 * DB.markAsDirty(customer); 397 * DB.save(customer); 398 * 399 * }</pre> 400 */ 401 public static void markAsDirty(Object bean) throws OptimisticLockException { 402 getDefault().markAsDirty(bean); 403 } 404 405 /** 406 * Saves the bean using an update. If you know you are updating a bean then it is preferrable to 407 * use this update() method rather than save(). 408 * <p> 409 * <b>Stateless updates:</b> Note that the bean does not have to be previously fetched to call 410 * update().You can create a new instance and set some of its properties programmatically for via 411 * JSON/XML marshalling etc. This is described as a 'stateless update'. 412 * </p> 413 * <p> 414 * <b>Optimistic Locking: </b> Note that if the version property is not set when update() is 415 * called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used). 416 * </p> 417 * <p> 418 * <pre>{@code 419 * 420 * // A 'stateless update' example 421 * Customer customer = new Customer(); 422 * customer.setId(7); 423 * customer.setName("ModifiedNameNoOCC"); 424 * database.update(customer); 425 * 426 * }</pre> 427 */ 428 public static void update(Object bean) throws OptimisticLockException { 429 getDefault().update(bean); 430 } 431 432 /** 433 * Update the beans in the collection. 434 */ 435 public static void updateAll(Collection<?> beans) throws OptimisticLockException { 436 getDefault().updateAll(beans); 437 } 438 439 /** 440 * Merge the bean using the default merge options. 441 * 442 * @param bean The bean to merge 443 */ 444 public static void merge(Object bean) { 445 getDefault().merge(bean); 446 } 447 448 /** 449 * Merge the bean using the given merge options. 450 * 451 * @param bean The bean to merge 452 * @param options The options to control the merge 453 */ 454 public static void merge(Object bean, MergeOptions options) { 455 getDefault().merge(bean, options); 456 } 457 458 /** 459 * Save all the beans from a Collection. 460 */ 461 public static int saveAll(Collection<?> beans) throws OptimisticLockException { 462 return getDefault().saveAll(beans); 463 } 464 465 /** 466 * Save all the beans from a Collection. 467 */ 468 public static int saveAll(Object... beans) throws OptimisticLockException { 469 return getDefault().saveAll(beans); 470 } 471 472 /** 473 * This method checks the uniqueness of a bean. I.e. if the save will work. It will return the 474 * properties that violates an unique / primary key. This may be done in an UI save action to 475 * validate if the user has entered correct values. 476 * <p> 477 * Note: This method queries the DB for uniqueness of all indices, so do not use it in a batch update. 478 * <p> 479 * Note: This checks only the root bean! 480 * <p> 481 * <pre>{@code 482 * 483 * // there is a unique constraint on title 484 * 485 * Document doc = new Document(); 486 * doc.setTitle("One flew over the cuckoo's nest"); 487 * doc.setBody("clashes with doc1"); 488 * 489 * Set<Property> properties = DB.checkUniqueness(doc); 490 * 491 * if (properties.isEmpty()) { 492 * // it is unique ... carry on 493 * 494 * } else { 495 * // build a user friendly message 496 * // to return message back to user 497 * 498 * String uniqueProperties = properties.toString(); 499 * 500 * StringBuilder msg = new StringBuilder(); 501 * 502 * properties.forEach((it)-> { 503 * Object propertyValue = it.getVal(doc); 504 * String propertyName = it.getName(); 505 * msg.append(" property["+propertyName+"] value["+propertyValue+"]"); 506 * }); 507 * 508 * // uniqueProperties > [title] 509 * // custom msg > property[title] value[One flew over the cuckoo's nest] 510 * 511 * } 512 * 513 * }</pre> 514 * 515 * @param bean The entity bean to check uniqueness on 516 * @return a set of Properties if constraint validation was detected or empty list. 517 */ 518 @Nonnull 519 public static Set<Property> checkUniqueness(Object bean) { 520 return getDefault().checkUniqueness(bean); 521 } 522 523 /** 524 * Same as {@link #checkUniqueness(Object)}. but with given transaction. 525 */ 526 @Nonnull 527 public static Set<Property> checkUniqueness(Object bean, Transaction transaction) { 528 return getDefault().checkUniqueness(bean, transaction); 529 } 530 531 /** 532 * Delete the bean. 533 * <p> 534 * This will return true if the bean was deleted successfully or JDBC batch is being used. 535 * </p> 536 * <p> 537 * If there is no current transaction one will be created and committed for 538 * you automatically. 539 * </p> 540 * <p> 541 * If the bean is configured with <code>@SoftDelete</code> then this will perform a soft 542 * delete rather than a hard/permanent delete. 543 * </p> 544 * <p> 545 * If the Bean does not have a version property (or loaded version property) and 546 * the bean does not exist then this returns false indicating that nothing was 547 * deleted. Note that, if JDBC batch mode is used then this always returns true. 548 * </p> 549 */ 550 public static boolean delete(Object bean) throws OptimisticLockException { 551 return getDefault().delete(bean); 552 } 553 554 /** 555 * Delete the bean in permanent fashion (will not use soft delete). 556 */ 557 public static boolean deletePermanent(Object bean) throws OptimisticLockException { 558 return getDefault().deletePermanent(bean); 559 } 560 561 /** 562 * Delete the bean given its type and id. 563 */ 564 public static int delete(Class<?> beanType, Object id) { 565 return getDefault().delete(beanType, id); 566 } 567 568 /** 569 * Delete permanent the bean given its type and id. 570 */ 571 public static int deletePermanent(Class<?> beanType, Object id) { 572 return getDefault().deletePermanent(beanType, id); 573 } 574 575 /** 576 * Delete several beans given their type and id values. 577 */ 578 public static int deleteAll(Class<?> beanType, Collection<?> ids) { 579 return getDefault().deleteAll(beanType, ids); 580 } 581 582 /** 583 * Delete permanent several beans given their type and id values. 584 */ 585 public static int deleteAllPermanent(Class<?> beanType, Collection<?> ids) { 586 return getDefault().deleteAllPermanent(beanType, ids); 587 } 588 589 /** 590 * Delete all the beans in the Collection. 591 */ 592 public static int deleteAll(Collection<?> beans) throws OptimisticLockException { 593 return getDefault().deleteAll(beans); 594 } 595 596 /** 597 * Delete permanent all the beans in the Collection (will not use soft delete). 598 */ 599 public static int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException { 600 return getDefault().deleteAllPermanent(beans); 601 } 602 603 /** 604 * Refresh the values of a bean. 605 * <p> 606 * Note that this resets OneToMany and ManyToMany properties so that if they 607 * are accessed a lazy load will refresh the many property. 608 * </p> 609 */ 610 public static void refresh(Object bean) { 611 getDefault().refresh(bean); 612 } 613 614 /** 615 * Refresh a 'many' property of a bean. 616 * <pre>{@code 617 * 618 * Order order = ...; 619 * ... 620 * // refresh the order details... 621 * DB.refreshMany(order, "details"); 622 * 623 * }</pre> 624 * 625 * @param bean the entity bean containing the List Set or Map to refresh. 626 * @param manyPropertyName the property name of the List Set or Map to refresh. 627 */ 628 public static void refreshMany(Object bean, String manyPropertyName) { 629 getDefault().refreshMany(bean, manyPropertyName); 630 } 631 632 /** 633 * Get a reference object. 634 * <p> 635 * This is sometimes described as a proxy (with lazy loading). 636 * </p> 637 * <pre>{@code 638 * 639 * Product product = DB.getReference(Product.class, 1); 640 * 641 * // You can get the id without causing a fetch/lazy load 642 * Integer productId = product.getId(); 643 * 644 * // If you try to get any other property a fetch/lazy loading will occur 645 * // This will cause a query to execute... 646 * String name = product.getName(); 647 * 648 * }</pre> 649 * 650 * @param beanType the type of entity bean 651 * @param id the id value 652 */ 653 public static <T> T getReference(Class<T> beanType, Object id) { 654 return getDefault().getReference(beanType, id); 655 } 656 657 /** 658 * Sort the list using the sortByClause which can contain a comma delimited 659 * list of property names and keywords asc, desc, nullsHigh and nullsLow. 660 * <ul> 661 * <li>asc - ascending order (which is the default)</li> 662 * <li>desc - Descending order</li> 663 * <li>nullsHigh - Treat null values as high/large values (which is the 664 * default)</li> 665 * <li>nullsLow- Treat null values as low/very small values</li> 666 * </ul> 667 * <p> 668 * If you leave off any keywords the defaults are ascending order and treating 669 * nulls as high values. 670 * </p> 671 * <p> 672 * Note that the sorting uses a Comparator and Collections.sort(); and does 673 * not invoke a DB query. 674 * </p> 675 * <pre>{@code 676 * 677 * // find orders and their customers 678 * List<Order> list = DB.find(Order.class) 679 * .fetch("customer") 680 * .order("id") 681 * .findList(); 682 * 683 * // sort by customer name ascending, then by order shipDate 684 * // ... then by the order status descending 685 * DB.sort(list, "customer.name, shipDate, status desc"); 686 * 687 * // sort by customer name descending (with nulls low) 688 * // ... then by the order id 689 * DB.sort(list, "customer.name desc nullsLow, id"); 690 * 691 * }</pre> 692 * 693 * @param list the list of entity beans 694 * @param sortByClause the properties to sort the list by 695 */ 696 public static <T> void sort(List<T> list, String sortByClause) { 697 getDefault().sort(list, sortByClause); 698 } 699 700 /** 701 * Find a bean using its unique id. This will not use caching. 702 * <pre>{@code 703 * 704 * // Fetch order 1 705 * Order order = DB.find(Order.class, 1); 706 * 707 * }</pre> 708 * <p> 709 * If you want more control over the query then you can use createQuery() and 710 * Query.findOne(); 711 * </p> 712 * <pre>{@code 713 * 714 * // ... additionally fetching customer, customer shipping address, 715 * // order details, and the product associated with each order detail. 716 * // note: only product id and name is fetch (its a "partial object"). 717 * // note: all other objects use "*" and have all their properties fetched. 718 * 719 * Query<Order> query = DB.find(Order.class) 720 * .setId(1) 721 * .fetch("customer") 722 * .fetch("customer.shippingAddress") 723 * .fetch("details") 724 * .query(); 725 * 726 * // fetch associated products but only fetch their product id and name 727 * query.fetch("details.product", "name"); 728 * 729 * // traverse the object graph... 730 * 731 * Order order = query.findOne(); 732 * 733 * Customer customer = order.getCustomer(); 734 * Address shippingAddress = customer.getShippingAddress(); 735 * List<OrderDetail> details = order.getDetails(); 736 * OrderDetail detail0 = details.get(0); 737 * Product product = detail0.getProduct(); 738 * String productName = product.getName(); 739 * 740 * }</pre> 741 * 742 * @param beanType the type of entity bean to fetch 743 * @param id the id value 744 */ 745 @Nullable 746 public static <T> T find(Class<T> beanType, Object id) { 747 return getDefault().find(beanType, id); 748 } 749 750 /** 751 * Look to execute a native sql query that does not returns beans but instead 752 * returns SqlRow or direct access to ResultSet (see {@link SqlQuery#findList(RowMapper)}. 753 * 754 * <p> 755 * Refer to {@link DtoQuery} for native sql queries returning DTO beans. 756 * </p> 757 * <p> 758 * Refer to {@link #findNative(Class, String)} for native sql queries returning entity beans. 759 * </p> 760 */ 761 public static SqlQuery sqlQuery(String sql) { 762 return getDefault().sqlQuery(sql); 763 } 764 765 /** 766 * Deprecated - migrate to sqlQuery(). 767 * <p> 768 * This is an alias for {@link #sqlQuery(String)}. 769 */ 770 @Deprecated 771 public static SqlQuery createSqlQuery(String sql) { 772 return sqlQuery(sql); 773 } 774 775 /** 776 * Look to execute a native sql insert update or delete statement. 777 * <p> 778 * Use this to execute a Insert Update or Delete statement. The statement will 779 * be native to the database and contain database table and column names. 780 * </p> 781 * 782 * <p> 783 * See {@link SqlUpdate} for example usage. 784 * </p> 785 * 786 * @return The SqlUpdate instance to set parameters and execute 787 */ 788 public static SqlUpdate sqlUpdate(String sql) { 789 return getDefault().sqlUpdate(sql); 790 } 791 792 /** 793 * Deprecated - migrate to sqlUpdate(). 794 * <p> 795 * This is an alias for {@link #sqlUpdate(String)}. 796 */ 797 @Deprecated 798 public static SqlUpdate createSqlUpdate(String sql) { 799 return sqlUpdate(sql); 800 } 801 802 /** 803 * Create a CallableSql to execute a given stored procedure. 804 * 805 * @see CallableSql 806 */ 807 public static CallableSql createCallableSql(String sql) { 808 return getDefault().createCallableSql(sql); 809 } 810 811 /** 812 * Create a orm update where you will supply the insert/update or delete 813 * statement (rather than using a named one that is already defined using the 814 * @NamedUpdates annotation). 815 * <p> 816 * The orm update differs from the sql update in that it you can use the bean 817 * name and bean property names rather than table and column names. 818 * </p> 819 * <p> 820 * An example: 821 * </p> 822 * <pre>{@code 823 * 824 * // The bean name and properties - "topic","postCount" and "id" 825 * 826 * // will be converted into their associated table and column names 827 * String updStatement = "update topic set postCount = :pc where id = :id"; 828 * 829 * Update<Topic> update = DB.createUpdate(Topic.class, updStatement); 830 * 831 * update.set("pc", 9); 832 * update.set("id", 3); 833 * 834 * int rows = update.execute(); 835 * System.out.println("rows updated:" + rows); 836 * 837 * }</pre> 838 */ 839 public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) { 840 841 return getDefault().createUpdate(beanType, ormUpdate); 842 } 843 844 /** 845 * Create a CsvReader for a given beanType. 846 */ 847 public static <T> CsvReader<T> createCsvReader(Class<T> beanType) { 848 849 return getDefault().createCsvReader(beanType); 850 } 851 852 /** 853 * Create a named query. 854 * <p> 855 * For RawSql the named query is expected to be in ebean.xml. 856 * </p> 857 * 858 * @param beanType The type of entity bean 859 * @param namedQuery The name of the query 860 * @param <T> The type of entity bean 861 * @return The query 862 */ 863 public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) { 864 return getDefault().createNamedQuery(beanType, namedQuery); 865 } 866 867 /** 868 * Create a query for a type of entity bean. 869 * <p> 870 * You can use the methods on the Query object to specify fetch paths, 871 * predicates, order by, limits etc. 872 * </p> 873 * <p> 874 * You then use findList(), findSet(), findMap() and findOne() to execute 875 * the query and return the collection or bean. 876 * </p> 877 * <p> 878 * Note that a query executed by {@link Query#findList()} etc will execute against 879 * the same database from which is was created. 880 * </p> 881 * 882 * @param beanType the class of entity to be fetched 883 * @return A ORM Query for this beanType 884 */ 885 public static <T> Query<T> createQuery(Class<T> beanType) { 886 887 return getDefault().createQuery(beanType); 888 } 889 890 /** 891 * Parse the Ebean query language statement returning the query which can then 892 * be modified (add expressions, change order by clause, change maxRows, change 893 * fetch and select paths etc). 894 * <p> 895 * <h3>Example</h3> 896 * <pre>{@code 897 * 898 * // Find order additionally fetching the customer, details and details.product name. 899 * 900 * String eql = "fetch customer fetch details fetch details.product (name) where id = :orderId "; 901 * 902 * Query<Order> query = DB.createQuery(Order.class, eql); 903 * query.setParameter("orderId", 2); 904 * 905 * Order order = query.findOne(); 906 * 907 * // This is the same as: 908 * 909 * Order order = DB.find(Order.class) 910 * .fetch("customer") 911 * .fetch("details") 912 * .fetch("detail.product", "name") 913 * .setId(2) 914 * .findOne(); 915 * 916 * }</pre> 917 * 918 * @param beanType The type of bean to fetch 919 * @param eql The Ebean query 920 * @param <T> The type of the entity bean 921 * @return The query with expressions defined as per the parsed query statement 922 */ 923 public static <T> Query<T> createQuery(Class<T> beanType, String eql) { 924 925 return getDefault().createQuery(beanType, eql); 926 } 927 928 /** 929 * Create a query for a type of entity bean. 930 * <p> 931 * This is actually the same as {@link #createQuery(Class)}. The reason it 932 * exists is that people used to JPA will probably be looking for a 933 * createQuery method (the same as entityManager). 934 * </p> 935 * 936 * @param beanType the type of entity bean to find 937 * @return A ORM Query object for this beanType 938 */ 939 public static <T> Query<T> find(Class<T> beanType) { 940 941 return getDefault().find(beanType); 942 } 943 944 /** 945 * Create a query using native SQL. 946 * <p> 947 * The native SQL can contain named parameters or positioned parameters. 948 * </p> 949 * <pre>{@code 950 * 951 * String sql = "select c.id, c.name from customer c where c.name like ? order by c.name"; 952 * 953 * Query<Customer> query = database.findNative(Customer.class, sql); 954 * query.setParameter(1, "Rob%"); 955 * 956 * List<Customer> customers = query.findList(); 957 * 958 * }</pre> 959 * 960 * @param beanType The type of entity bean to fetch 961 * @param nativeSql The SQL that can contain named or positioned parameters 962 * @return The query to set parameters and execute 963 */ 964 public static <T> Query<T> findNative(Class<T> beanType, String nativeSql) { 965 return getDefault().findNative(beanType, nativeSql); 966 } 967 968 /** 969 * Create a Query for DTO beans. 970 * <p> 971 * DTO beans are just normal bean like classes with public constructor(s) and setters. 972 * They do not need to be registered with Ebean before use. 973 * </p> 974 * 975 * @param dtoType The type of the DTO bean the rows will be mapped into. 976 * @param sql The SQL query to execute. 977 * @param <T> The type of the DTO bean. 978 */ 979 public static <T> DtoQuery<T> findDto(Class<T> dtoType, String sql) { 980 return getDefault().findDto(dtoType, sql); 981 } 982 983 /** 984 * Create an Update query to perform a bulk update. 985 * <p> 986 * <pre>{@code 987 * 988 * int rows = DB.update(Customer.class) 989 * .set("status", Customer.Status.ACTIVE) 990 * .set("updtime", new Timestamp(System.currentTimeMillis())) 991 * .where() 992 * .gt("id", 1000) 993 * .update(); 994 * 995 * }</pre> 996 * 997 * @param beanType The type of entity bean to update 998 * @param <T> The type of entity bean 999 * @return The update query to use 1000 */ 1001 public static <T> UpdateQuery<T> update(Class<T> beanType) { 1002 return getDefault().update(beanType); 1003 } 1004 1005 /** 1006 * Create a filter for sorting and filtering lists of entities locally without 1007 * going back to the database. 1008 * <p> 1009 * This produces and returns a new list with the sort and filters applied. 1010 * </p> 1011 * <p> 1012 * Refer to {@link Filter} for an example of its use. 1013 * </p> 1014 */ 1015 public static <T> Filter<T> filter(Class<T> beanType) { 1016 return getDefault().filter(beanType); 1017 } 1018 1019// /** 1020// * Execute a Sql Update Delete or Insert statement. This returns the number of 1021// * rows that where updated, deleted or inserted. If is executed in batch then 1022// * this returns -1. You can get the actual rowCount after commit() from 1023// * updateSql.getRowCount(). 1024// * <p> 1025// * If you wish to execute a Sql Select natively then you should use the 1026// * FindByNativeSql object. 1027// * </p> 1028// * <p> 1029// * Note that the table modification information is automatically deduced and 1030// * you do not need to call the DB.externalModification() method when you 1031// * use this method. 1032// * </p> 1033// * <p> 1034// * Example: 1035// * </p> 1036// * <pre>{@code 1037// * 1038// * // example that uses 'named' parameters 1039// * String s = "UPDATE f_topic set post_count = :count where id = :id" 1040// * 1041// * SqlUpdate update = DB.createSqlUpdate(s); 1042// * 1043// * update.setParameter("id", 1); 1044// * update.setParameter("count", 50); 1045// * 1046// * int modifiedCount = DB.execute(update); 1047// * 1048// * String msg = "There where " + modifiedCount + "rows updated"; 1049// * 1050// * }</pre> 1051// * 1052// * @param sqlUpdate the update sql potentially with bind values 1053// * @return the number of rows updated or deleted. -1 if executed in batch. 1054// * @see SqlUpdate 1055// * @see CallableSql 1056// * @see DB#execute(CallableSql) 1057// */ 1058// public static int execute(SqlUpdate sqlUpdate) { 1059// return defaultDatabase().execute(sqlUpdate); 1060// } 1061// 1062// /** 1063// * For making calls to stored procedures. 1064// * <p> 1065// * Example: 1066// * </p> 1067// * <pre>{@code 1068// * 1069// * String sql = "{call sp_order_modify(?,?,?)}"; 1070// * 1071// * CallableSql cs = DB.createCallableSql(sql); 1072// * cs.setParameter(1, 27); 1073// * cs.setParameter(2, "SHIPPED"); 1074// * cs.registerOut(3, Types.INTEGER); 1075// * 1076// * DB.execute(cs); 1077// * 1078// * // read the out parameter 1079// * Integer returnValue = (Integer) cs.getObject(3); 1080// * 1081// * }</pre> 1082// * 1083// * @see CallableSql 1084// * @see Ebean#execute(SqlUpdate) 1085// */ 1086// public static int execute(CallableSql callableSql) { 1087// return defaultDatabase().execute(callableSql); 1088// } 1089 1090 /** 1091 * Execute a TxRunnable in a Transaction with an explicit scope. 1092 * <p> 1093 * The scope can control the transaction type, isolation and rollback 1094 * semantics. 1095 * </p> 1096 * <pre>{@code 1097 * 1098 * // set specific transactional scope settings 1099 * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE); 1100 * 1101 * DB.execute(scope, new TxRunnable() { 1102 * public void run() { 1103 * User u1 = DB.find(User.class, 1); 1104 * ... 1105 * } 1106 * }); 1107 * 1108 * }</pre> 1109 */ 1110 public static void execute(TxScope scope, Runnable r) { 1111 getDefault().execute(scope, r); 1112 } 1113 1114 /** 1115 * Execute a Runnable in a Transaction with the default scope. 1116 * <p> 1117 * The default scope runs with REQUIRED and by default will rollback on any 1118 * exception (checked or runtime). 1119 * </p> 1120 * <pre>{@code 1121 * 1122 * DB.execute(() -> { 1123 * 1124 * User u1 = DB.find(User.class, 1); 1125 * User u2 = DB.find(User.class, 2); 1126 * 1127 * u1.setName("u1 mod"); 1128 * u2.setName("u2 mod"); 1129 * 1130 * DB.save(u1); 1131 * DB.save(u2); 1132 * }); 1133 * }</pre> 1134 */ 1135 public static void execute(Runnable r) { 1136 getDefault().execute(r); 1137 } 1138 1139 /** 1140 * Execute a Callable in a Transaction with an explicit scope. 1141 * <p> 1142 * The scope can control the transaction type, isolation and rollback 1143 * semantics. 1144 * </p> 1145 * <pre>{@code 1146 * 1147 * // set specific transactional scope settings 1148 * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE); 1149 * 1150 * DB.executeCall(scope, new Callable<String>() { 1151 * public String call() { 1152 * User u1 = DB.find(User.class, 1); 1153 * ... 1154 * return u1.getEmail(); 1155 * } 1156 * }); 1157 * }</pre> 1158 */ 1159 public static <T> T executeCall(TxScope scope, Callable<T> c) { 1160 return getDefault().executeCall(scope, c); 1161 } 1162 1163 /** 1164 * Execute a Callable in a Transaction with the default scope. 1165 * <p> 1166 * The default scope runs with REQUIRED and by default will rollback on any 1167 * exception (checked or runtime). 1168 * </p> 1169 * <p> 1170 * This is basically the same as TxRunnable except that it returns an Object 1171 * (and you specify the return type via generics). 1172 * </p> 1173 * <pre>{@code 1174 * 1175 * DB.executeCall(() -> { 1176 * 1177 * User u1 = DB.find(User.class, 1); 1178 * User u2 = DB.find(User.class, 2); 1179 * 1180 * u1.setName("u1 mod"); 1181 * u2.setName("u2 mod"); 1182 * 1183 * DB.save(u1); 1184 * DB.save(u2); 1185 * 1186 * return u1.getEmail(); 1187 * }); 1188 * }</pre> 1189 */ 1190 public static <T> T executeCall(Callable<T> c) { 1191 return getDefault().executeCall(c); 1192 } 1193 1194 /** 1195 * Inform Ebean that tables have been modified externally. These could be the 1196 * result of from calling a stored procedure, other JDBC calls or external 1197 * programs including other frameworks. 1198 * <p> 1199 * If you use DB.execute(UpdateSql) then the table modification information 1200 * is automatically deduced and you do not need to call this method yourself. 1201 * </p> 1202 * <p> 1203 * This information is used to invalidate objects out of the cache and 1204 * potentially text indexes. This information is also automatically broadcast 1205 * across the cluster. 1206 * </p> 1207 * <p> 1208 * If there is a transaction then this information is placed into the current 1209 * transactions event information. When the transaction is committed this 1210 * information is registered (with the transaction manager). If this 1211 * transaction is rolled back then none of the transaction event information 1212 * registers including the information you put in via this method. 1213 * </p> 1214 * <p> 1215 * If there is NO current transaction when you call this method then this 1216 * information is registered immediately (with the transaction manager). 1217 * </p> 1218 * 1219 * @param tableName the name of the table that was modified 1220 * @param inserts true if rows where inserted into the table 1221 * @param updates true if rows on the table where updated 1222 * @param deletes true if rows on the table where deleted 1223 */ 1224 public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) { 1225 getDefault().externalModification(tableName, inserts, updates, deletes); 1226 } 1227 1228 /** 1229 * Return the BeanState for a given entity bean. 1230 * <p> 1231 * This will return null if the bean is not an enhanced entity bean. 1232 * </p> 1233 */ 1234 public static BeanState getBeanState(Object bean) { 1235 return getDefault().getBeanState(bean); 1236 } 1237 1238 /** 1239 * Return the value of the Id property for a given bean. 1240 */ 1241 public static Object getBeanId(Object bean) { 1242 return getDefault().getBeanId(bean); 1243 } 1244 1245 /** 1246 * Return the manager of the level 2 cache ("L2" cache). 1247 */ 1248 public static ServerCacheManager getServerCacheManager() { 1249 return getDefault().getServerCacheManager(); 1250 } 1251 1252 /** 1253 * Return the BackgroundExecutor service for asynchronous processing of 1254 * queries. 1255 */ 1256 public static BackgroundExecutor getBackgroundExecutor() { 1257 return getDefault().getBackgroundExecutor(); 1258 } 1259 1260 /** 1261 * Return the JsonContext for reading/writing JSON. 1262 */ 1263 public static JsonContext json() { 1264 return getDefault().json(); 1265 } 1266 1267 /** 1268 * Truncate the base tables for the given bean types. 1269 */ 1270 public static void truncate(Class<?>... types) { 1271 getDefault().truncate(types); 1272 } 1273 1274 /** 1275 * Truncate the given tables. 1276 */ 1277 public static void truncate(String... tables) { 1278 getDefault().truncate(tables); 1279 } 1280 1281}