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