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