001package com.avaje.ebean; 002 003import org.jetbrains.annotations.Nullable; 004 005import javax.persistence.NonUniqueResultException; 006import java.sql.Timestamp; 007import java.util.List; 008import java.util.Map; 009import java.util.Set; 010 011/** 012 * Object relational query for finding a List, Set, Map or single entity bean. 013 * <p> 014 * Example: Create the query using the API. 015 * </p> 016 * <p> 017 * <pre>{@code 018 * 019 * List<Order> orderList = 020 * ebeanServer.find(Order.class) 021 * .fetch("customer") 022 * .fetch("details") 023 * .where() 024 * .like("customer.name","rob%") 025 * .gt("orderDate",lastWeek) 026 * .orderBy("customer.id, id desc") 027 * .setMaxRows(50) 028 * .findList(); 029 * 030 * ... 031 * }</pre> 032 * <p> 033 * Example: The same query using the query language 034 * </p> 035 * <pre>{@code 036 * 037 * String oql = 038 * +" fetch customer " 039 * +" fetch details " 040 * +" where customer.name like :custName and orderDate > :minOrderDate " 041 * +" order by customer.id, id desc " 042 * +" limit 50 "; 043 * 044 * Query<Order> query = ebeanServer.createQuery(Order.class, oql); 045 * query.setParameter("custName", "Rob%"); 046 * query.setParameter("minOrderDate", lastWeek); 047 * 048 * List<Order> orderList = query.findList(); 049 * ... 050 * }</pre> 051 * <p> 052 * Example: Using a named query called "with.cust.and.details" 053 * </p> 054 * <pre>{@code 055 * 056 * Query<Order> query = ebeanServer.createNamedQuery(Order.class,"with.cust.and.details"); 057 * query.setParameter("custName", "Rob%"); 058 * query.setParameter("minOrderDate", lastWeek); 059 * 060 * List<Order> orderList = query.findList(); 061 * ... 062 * }</pre> 063 * <h3>AutoTune</h3> 064 * <p> 065 * Ebean has built in support for "AutoTune". This is a mechanism where a query 066 * can be automatically tuned based on profiling information that is collected. 067 * </p> 068 * <p> 069 * This is effectively the same as automatically using select() and fetch() to 070 * build a query that will fetch all the data required by the application and no 071 * more. 072 * </p> 073 * <p> 074 * It is expected that AutoTune will be the default approach for many queries 075 * in a system. It is possibly not as useful where the result of a query is sent 076 * to a remote client or where there is some requirement for "Read Consistency" 077 * guarantees. 078 * </p> 079 * <h3>Query Language</h3> 080 * <p> 081 * <b>Partial Objects</b> 082 * </p> 083 * <p> 084 * The <em>find</em> and <em>fetch</em> clauses support specifying a list of 085 * properties to fetch. This results in objects that are "partially populated". 086 * If you try to get a property that was not populated a "lazy loading" query 087 * will automatically fire and load the rest of the properties of the bean (This 088 * is very similar behaviour as a reference object being "lazy loaded"). 089 * </p> 090 * <p> 091 * Partial objects can be saved just like fully populated objects. If you do 092 * this you should remember to include the <em>"Version"</em> property in the 093 * initial fetch. If you do not include a version property then optimistic 094 * concurrency checking will occur but only include the fetched properties. 095 * Refer to "ALL Properties/Columns" mode of Optimistic Concurrency checking. 096 * </p> 097 * <pre>{@code 098 * [ select [ ( * | {fetch properties} ) ] ] 099 * [ fetch {path} [ ( * | {fetch properties} ) ] ] 100 * [ where {predicates} ] 101 * [ order by {order by properties} ] 102 * [ limit {max rows} [ offset {first row} ] ] 103 * }</pre> 104 * <p> 105 * <b>SELECT</b> [ ( <i>*</i> | <i>{fetch properties}</i> ) ] 106 * </p> 107 * <p> 108 * With the select you can specify a list of properties to fetch. 109 * </p> 110 * <p> 111 * <b>FETCH</b> <b>{path}</b> [ ( <i>*</i> | <i>{fetch properties}</i> ) ] 112 * </p> 113 * <p> 114 * With the fetch you specify the associated property to fetch and populate. The 115 * path is a OneToOne, ManyToOne, OneToMany or ManyToMany property. 116 * </p> 117 * <p> 118 * For fetch of a path we can optionally specify a list of properties to fetch. 119 * If you do not specify a list of properties ALL the properties for that bean 120 * type are fetched. 121 * </p> 122 * <p> 123 * <b>WHERE</b> <b>{list of predicates}</b> 124 * </p> 125 * <p> 126 * The list of predicates which are joined by AND OR NOT ( and ). They can 127 * include named (or positioned) bind parameters. These parameters will need to 128 * be bound by {@link Query#setParameter(String, Object)}. 129 * </p> 130 * <p> 131 * <b>ORDER BY</b> <b>{order by properties}</b> 132 * </p> 133 * <p> 134 * The list of properties to order the result. You can include ASC (ascending) 135 * and DESC (descending) in the order by clause. 136 * </p> 137 * <p> 138 * <b>LIMIT</b> <b>{max rows}</b> [ OFFSET <i>{first row}</i> ] 139 * </p> 140 * <p> 141 * The limit offset specifies the max rows and first row to fetch. The offset is 142 * optional. 143 * </p> 144 * <h4>Examples of Ebean's Query Language</h4> 145 * <p> 146 * Find orders fetching its id, shipDate and status properties. Note that the id 147 * property is always fetched even if it is not included in the list of fetch 148 * properties. 149 * </p> 150 * <pre>{@code 151 * 152 * select (shipDate, status) 153 * 154 * }</pre> 155 * <p> 156 * Find orders with a named bind variable (that will need to be bound via 157 * {@link Query#setParameter(String, Object)}). 158 * </p> 159 * <pre>{@code 160 * 161 * where customer.name like :custLike 162 * 163 * }</pre> 164 * <p> 165 * Find orders and also fetch the customer with a named bind parameter. This 166 * will fetch and populate both the order and customer objects. 167 * </p> 168 * <pre>{@code 169 * 170 * fetch customer 171 * where customer.id = :custId 172 * 173 * }</pre> 174 * <p> 175 * Find orders and also fetch the customer, customer shippingAddress, order 176 * details and related product. Note that customer and product objects will be 177 * "Partial Objects" with only some of their properties populated. The customer 178 * objects will have their id, name and shipping address populated. The product 179 * objects (associated with each order detail) will have their id, sku and name 180 * populated. 181 * </p> 182 * <pre>{@code 183 * 184 * fetch customer (name) 185 * fetch customer.shippingAddress 186 * fetch details 187 * fetch details.product (sku, name) 188 * 189 * }</pre> 190 * 191 * @param <T> the type of Entity bean this query will fetch. 192 */ 193public interface Query<T> { 194 195 /** 196 * Return the RawSql that was set to use for this query. 197 */ 198 RawSql getRawSql(); 199 200 /** 201 * Set RawSql to use for this query. 202 */ 203 Query<T> setRawSql(RawSql rawSql); 204 205 /** 206 * Perform an 'As of' query using history tables to return the object graph 207 * as of a time in the past. 208 * <p> 209 * To perform this query the DB must have underlying history tables. 210 * </p> 211 * 212 * @param asOf the date time in the past at which you want to view the data 213 */ 214 Query<T> asOf(Timestamp asOf); 215 216 /** 217 * Execute the query against the draft set of tables. 218 */ 219 Query<T> asDraft(); 220 221 /** 222 * Cancel the query execution if supported by the underlying database and 223 * driver. 224 * <p> 225 * This must be called from a different thread to the query executor. 226 * </p> 227 */ 228 void cancel(); 229 230 /** 231 * Return a copy of the query. 232 * <p> 233 * This is so that you can use a Query as a "prototype" for creating other 234 * query instances. You could create a Query with various where expressions 235 * and use that as a "prototype" - using this copy() method to create a new 236 * instance that you can then add other expressions then execute. 237 * </p> 238 */ 239 Query<T> copy(); 240 241 /** 242 * Specify the PersistenceContextScope to use for this query. 243 * <p/> 244 * When this is not set the 'default' configured on {@link com.avaje.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)} 245 * is used - this value defaults to {@link PersistenceContextScope#TRANSACTION}. 246 * <p/> 247 * Note that the same persistence Context is used for subsequent lazy loading and query join queries. 248 * <p/> 249 * Note that #findEach uses a 'per object graph' PersistenceContext so this scope is ignored for 250 * queries executed as #findIterate, #findEach, #findEachWhile. 251 * 252 * @param scope The scope to use for this query and subsequent lazy loading. 253 */ 254 Query<T> setPersistenceContextScope(PersistenceContextScope scope); 255 256 /** 257 * Return the ExpressionFactory used by this query. 258 */ 259 ExpressionFactory getExpressionFactory(); 260 261 /** 262 * Returns true if this query was tuned by autoTune. 263 */ 264 boolean isAutoTuned(); 265 266 /** 267 * Explicitly specify whether to use AutoTune for this query. 268 * <p> 269 * If you do not call this method on a query the "Implicit AutoTune mode" is 270 * used to determine if AutoTune should be used for a given query. 271 * </p> 272 * <p> 273 * AutoTune can add additional fetch paths to the query and specify which 274 * properties are included for each path. If you have explicitly defined some 275 * fetch paths AutoTune will not remove them. 276 * </p> 277 */ 278 Query<T> setAutoTune(boolean autoTune); 279 280 /** 281 * Set the default lazy loading batch size to use. 282 * <p> 283 * When lazy loading is invoked on beans loaded by this query then this sets the 284 * batch size used to load those beans. 285 * 286 * @param lazyLoadBatchSize the number of beans to lazy load in a single batch 287 */ 288 Query<T> setLazyLoadBatchSize(int lazyLoadBatchSize); 289 290 /** 291 * Execute the query including soft deleted rows. 292 * <p> 293 * This means that Ebean will not add any predicates to the query for filtering out 294 * soft deleted rows. You can still add your own predicates for the deleted properties 295 * and effectively you have full control over the query to include or exclude soft deleted 296 * rows as needed for a given use case. 297 * </p> 298 */ 299 Query<T> setIncludeSoftDeletes(); 300 301 /** 302 * Disable read auditing for this query. 303 * <p> 304 * This is intended to be used when the query is not a user initiated query and instead 305 * part of the internal processing in an application to load a cache or document store etc. 306 * In these cases we don't want the query to be part of read auditing. 307 * </p> 308 */ 309 Query<T> setDisableReadAuditing(); 310 311 /** 312 * Specify the properties to fetch on the root level entity bean in comma delimited format. 313 * <p> 314 * The Id property is automatically included in the properties to fetch unless setDistinct(true) 315 * is set on the query. 316 * </p> 317 * <p> 318 * Use {@link #fetch(String, String)} to specify specific properties to fetch 319 * on other non-root level paths of the object graph. 320 * </p> 321 * <pre>{@code 322 * 323 * List<Customer> customers = 324 * ebeanServer.find(Customer.class) 325 * // Only fetch the customer id, name and status. 326 * // This is described as a "Partial Object" 327 * .select("name, status") 328 * .where.ilike("name", "rob%") 329 * .findList(); 330 * 331 * }</pre> 332 * 333 * @param fetchProperties the properties to fetch for this bean (* = all properties). 334 */ 335 Query<T> select(String fetchProperties); 336 337 /** 338 * Specify a path to fetch eagerly including specific properties. 339 * <p> 340 * Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can 341 * not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean 342 * will automatically convert this fetch query into a "query join" - i.e. use fetchQuery(). 343 * </p> 344 * <pre>{@code 345 * 346 * // query orders... 347 * List<Order> orders = 348 * ebeanServer.find(Order.class) 349 * // fetch the customer... 350 * // ... getting the customers name and phone number 351 * .fetch("customer", "name, phoneNumber") 352 * 353 * // ... also fetch the customers billing address (* = all properties) 354 * .fetch("customer.billingAddress", "*") 355 * .findList(); 356 * }</pre> 357 * <p> 358 * If columns is null or "*" then all columns/properties for that path are fetched. 359 * </p> 360 * <pre>{@code 361 * 362 * // fetch customers (their id, name and status) 363 * List<Customer> customers = 364 * ebeanServer.find(Customer.class) 365 * .select("name, status") 366 * .fetch("contacts", "firstName,lastName,email") 367 * .findList(); 368 * 369 * }</pre> 370 * 371 * @param path the property path we wish to fetch eagerly. 372 * @param fetchProperties properties of the associated bean that you want to include in the 373 * fetch (* means all properties, null also means all properties). 374 */ 375 Query<T> fetch(String path, String fetchProperties); 376 377 /** 378 * Fetch the path and properties using a "query join" (separate SQL query). 379 * <p> 380 * This is the same as: 381 * </p> 382 * <pre>{@code 383 * 384 * fetch(path, fetchProperties, new FetchConfig().query()) 385 * 386 * }</pre> 387 * <p> 388 * This would be used instead of a fetch() when we use a separate SQL query to fetch this 389 * part of the object graph rather than a SQL join. 390 * </p> 391 * <p> 392 * We might typically get a performance benefit when the path to fetch is a OneToMany 393 * or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many 394 * is high. 395 * </p> 396 * 397 * @param path the property path we wish to fetch eagerly. 398 * @param fetchProperties properties of the associated bean that you want to include in the 399 * fetch (* means all properties, null also means all properties). 400 */ 401 Query<T> fetchQuery(String path, String fetchProperties); 402 403 /** 404 * Fetch the path and properties lazily (via batch lazy loading). 405 * <p> 406 * This is the same as: 407 * </p> 408 * <pre>{@code 409 * 410 * fetch(path, fetchProperties, new FetchConfig().lazy()) 411 * 412 * }</pre> 413 * <p> 414 * The reason for using fetchLazy() is to either: 415 * </p> 416 * <ul> 417 * <li>Control/tune what is fetched as part of lazy loading</li> 418 * <li>Make use of the L2 cache, build this part of the graph from L2 cache</li> 419 * </ul> 420 * 421 * @param path the property path we wish to fetch lazily. 422 * @param fetchProperties properties of the associated bean that you want to include in the 423 * fetch (* means all properties, null also means all properties). 424 */ 425 Query<T> fetchLazy(String path, String fetchProperties); 426 427 /** 428 * Additionally specify a FetchConfig to use a separate query or lazy loading 429 * to load this path. 430 * <pre>{@code 431 * 432 * // fetch customers (their id, name and status) 433 * List<Customer> customers = 434 * ebeanServer.find(Customer.class) 435 * .select("name, status") 436 * .fetch("contacts", "firstName,lastName,email", new FetchConfig().lazy(10)) 437 * .findList(); 438 * 439 * }</pre> 440 * 441 * @param path the property path we wish to fetch eagerly. 442 */ 443 Query<T> fetch(String path, String fetchProperties, FetchConfig fetchConfig); 444 445 /** 446 * Specify a path to fetch eagerly including all its properties. 447 * <p> 448 * Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can 449 * not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean 450 * will automatically convert this fetch query into a "query join" - i.e. use fetchQuery(). 451 * </p> 452 * <pre>{@code 453 * 454 * // fetch customers (their id, name and status) 455 * List<Customer> customers = 456 * ebeanServer.find(Customer.class) 457 * // eager fetch the contacts 458 * .fetch("contacts") 459 * .findList(); 460 * 461 * }</pre> 462 * 463 * @param path the property path we wish to fetch eagerly. 464 */ 465 Query<T> fetch(String path); 466 467 /** 468 * Fetch the path eagerly using a "query join" (separate SQL query). 469 * <p> 470 * This is the same as: 471 * </p> 472 * <pre>{@code 473 * 474 * fetch(path, new FetchConfig().query()) 475 * 476 * }</pre> 477 * <p> 478 * This would be used instead of a fetch() when we use a separate SQL query to fetch this 479 * part of the object graph rather than a SQL join. 480 * </p> 481 * <p> 482 * We might typically get a performance benefit when the path to fetch is a OneToMany 483 * or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many 484 * is high. 485 * </p> 486 * 487 * @param path the property path we wish to fetch eagerly 488 */ 489 Query<T> fetchQuery(String path); 490 491 /** 492 * Fetch the path lazily (via batch lazy loading). 493 * <p> 494 * This is the same as: 495 * </p> 496 * <pre>{@code 497 * 498 * fetch(path, new FetchConfig().lazy()) 499 * 500 * }</pre> 501 * <p> 502 * The reason for using fetchLazy() is to either: 503 * </p> 504 * <ul> 505 * <li>Control/tune what is fetched as part of lazy loading</li> 506 * <li>Make use of the L2 cache, build this part of the graph from L2 cache</li> 507 * </ul> 508 * 509 * @param path the property path we wish to fetch lazily. 510 */ 511 Query<T> fetchLazy(String path); 512 513 /** 514 * Additionally specify a JoinConfig to specify a "query join" and or define 515 * the lazy loading query. 516 * <pre>{@code 517 * 518 * // fetch customers (their id, name and status) 519 * List<Customer> customers = 520 * ebeanServer.find(Customer.class) 521 * // lazy fetch contacts with a batch size of 100 522 * .fetch("contacts", new FetchConfig().lazy(100)) 523 * .findList(); 524 * 525 * }</pre> 526 */ 527 Query<T> fetch(String path, FetchConfig fetchConfig); 528 529 /** 530 * Apply the path properties replacing the select and fetch clauses. 531 * <p> 532 * This is typically used when the FetchPath is applied to both the query and the JSON output. 533 * </p> 534 */ 535 Query<T> apply(FetchPath fetchPath); 536 537 /** 538 * Execute the query returning the list of Id's. 539 * <p> 540 * This query will execute against the EbeanServer that was used to create it. 541 * </p> 542 * 543 * @see EbeanServer#findIds(Query, Transaction) 544 */ 545 List<Object> findIds(); 546 547 /** 548 * Execute the query processing the beans one at a time. 549 * <p> 550 * This method is appropriate to process very large query results as the 551 * beans are consumed one at a time and do not need to be held in memory 552 * (unlike #findList #findSet etc) 553 * </p> 554 * <p> 555 * Note that internally Ebean can inform the JDBC driver that it is expecting larger 556 * resultSet and specifically for MySQL this hint is required to stop it's JDBC driver 557 * from buffering the entire resultSet. As such, for smaller resultSets findList() is 558 * generally preferable. 559 * </p> 560 * <p> 561 * Compared with #findEachWhile this will always process all the beans where as 562 * #findEachWhile provides a way to stop processing the query result early before 563 * all the beans have been read. 564 * </p> 565 * <p> 566 * This method is functionally equivalent to findIterate() but instead of using an 567 * iterator uses the QueryEachConsumer (SAM) interface which is better suited to use 568 * with Java8 closures. 569 * </p> 570 * <pre>{@code 571 * 572 * ebeanServer.find(Customer.class) 573 * .where().eq("status", Status.NEW) 574 * .order().asc("id") 575 * .findEach((Customer customer) -> { 576 * 577 * // do something with customer 578 * System.out.println("-- visit " + customer); 579 * }); 580 * 581 * }</pre> 582 * 583 * @param consumer the consumer used to process the queried beans. 584 */ 585 void findEach(QueryEachConsumer<T> consumer); 586 587 /** 588 * Execute the query using callbacks to a visitor to process the resulting 589 * beans one at a time. 590 * <p> 591 * This method is functionally equivalent to findIterate() but instead of using an 592 * iterator uses the QueryEachWhileConsumer (SAM) interface which is better suited to use 593 * with Java8 closures. 594 * </p> 595 * <pre>{@code 596 * 597 * ebeanServer.find(Customer.class) 598 * .fetch("contacts", new FetchConfig().query(2)) 599 * .where().eq("status", Status.NEW) 600 * .order().asc("id") 601 * .setMaxRows(2000) 602 * .findEachWhile((Customer customer) -> { 603 * 604 * // do something with customer 605 * System.out.println("-- visit " + customer); 606 * 607 * // return true to continue processing or false to stop 608 * return (customer.getId() < 40); 609 * }); 610 * 611 * }</pre> 612 * 613 * @param consumer the consumer used to process the queried beans. 614 */ 615 void findEachWhile(QueryEachWhileConsumer<T> consumer); 616 617 /** 618 * Execute the query returning the list of objects. 619 * <p> 620 * This query will execute against the EbeanServer that was used to create it. 621 * </p> 622 * <pre>{@code 623 * 624 * List<Customer> customers = 625 * ebeanServer.find(Customer.class) 626 * .where().ilike("name", "rob%") 627 * .findList(); 628 * 629 * }</pre> 630 * 631 * @see EbeanServer#findList(Query, Transaction) 632 */ 633 List<T> findList(); 634 635 /** 636 * Execute the query returning the set of objects. 637 * <p> 638 * This query will execute against the EbeanServer that was used to create it. 639 * </p> 640 * <pre>{@code 641 * 642 * Set<Customer> customers = 643 * ebeanServer.find(Customer.class) 644 * .where().ilike("name", "rob%") 645 * .findSet(); 646 * 647 * }</pre> 648 * 649 * @see EbeanServer#findSet(Query, Transaction) 650 */ 651 Set<T> findSet(); 652 653 /** 654 * Execute the query returning a map of the objects. 655 * <p> 656 * This query will execute against the EbeanServer that was used to create it. 657 * </p> 658 * <p> 659 * You can use setMapKey() so specify the property values to be used as keys 660 * on the map. If one is not specified then the id property is used. 661 * </p> 662 * <pre>{@code 663 * 664 * Map<?, Product> map = 665 * ebeanServer.find(Product.class) 666 * .setMapKey("sku") 667 * .findMap(); 668 * 669 * }</pre> 670 * 671 * @see EbeanServer#findMap(Query, Transaction) 672 */ 673 Map<?, T> findMap(); 674 675 /** 676 * Return a typed map specifying the key property and type. 677 */ 678 <K> Map<K, T> findMap(String keyProperty, Class<K> keyType); 679 680 /** 681 * Execute the query returning either a single bean or null (if no matching 682 * bean is found). 683 * <p> 684 * If more than 1 row is found for this query then a NonUniqueResultException is 685 * thrown. 686 * </p> 687 * <p> 688 * This is useful when your predicates dictate that your query should only 689 * return 0 or 1 results. 690 * </p> 691 * <pre>{@code 692 * 693 * // assuming the sku of products is unique... 694 * Product product = 695 * ebeanServer.find(Product.class) 696 * .where().eq("sku", "aa113") 697 * .findUnique(); 698 * ... 699 * }</pre> 700 * <p> 701 * It is also useful with finding objects by their id when you want to specify 702 * further join information. 703 * </p> 704 * <pre>{@code 705 * 706 * // Fetch order 1 and additionally fetch join its order details... 707 * Order order = 708 * ebeanServer.find(Order.class) 709 * .setId(1) 710 * .fetch("details") 711 * .findUnique(); 712 * 713 * // the order details were eagerly loaded 714 * List<OrderDetail> details = order.getDetails(); 715 * ... 716 * }</pre> 717 * 718 * @throws NonUniqueResultException if more than one result was found 719 */ 720 @Nullable 721 T findUnique(); 722 723 /** 724 * Return versions of a @History entity bean. 725 * <p> 726 * Note that this query will work against view based history implementations 727 * but not sql2011 standards based implementations that require a start and 728 * end timestamp to be specified. 729 * </p> 730 * <p> 731 * Generally this query is expected to be a find by id or unique predicates query. 732 * It will execute the query against the history returning the versions of the bean. 733 * </p> 734 */ 735 List<Version<T>> findVersions(); 736 737 /** 738 * Return versions of a @History entity bean between the 2 timestamps. 739 * <p> 740 * Generally this query is expected to be a find by id or unique predicates query. 741 * It will execute the query against the history returning the versions of the bean. 742 * </p> 743 */ 744 List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end); 745 746 /** 747 * Execute as a delete query deleting the 'root level' beans that match the predicates 748 * in the query. 749 * <p> 750 * Note that if the query includes joins then the generated delete statement may not be 751 * optimal depending on the database platform. 752 * </p> 753 * 754 * @return the number of beans/rows that were deleted. 755 */ 756 int delete(); 757 758 /** 759 * Execute the UpdateQuery returning the number of rows updated. 760 */ 761 int update(); 762 763 /** 764 * Return the count of entities this query should return. 765 * <p> 766 * This is the number of 'top level' or 'root level' entities. 767 * </p> 768 */ 769 int findCount(); 770 771 /** 772 * Deprecated in favor of findCount(). 773 * <p> 774 * Return the count of entities this query should return. 775 * 776 * @deprecated 777 */ 778 int findRowCount(); 779 780 /** 781 * Execute find row count query in a background thread. 782 * <p> 783 * This returns a Future object which can be used to cancel, check the 784 * execution status (isDone etc) and get the value (with or without a 785 * timeout). 786 * </p> 787 * 788 * @return a Future object for the row count query 789 */ 790 FutureRowCount<T> findFutureCount(); 791 792 /** 793 * Deprecated in favor of findFutureCount(). 794 * <p> 795 * Execute find row count query in a background thread. 796 * <p> 797 * This returns a Future object which can be used to cancel, check the 798 * execution status (isDone etc) and get the value (with or without a 799 * timeout). 800 * </p> 801 * 802 * @return a Future object for the row count query 803 * @deprecated 804 */ 805 FutureRowCount<T> findFutureRowCount(); 806 807 /** 808 * Execute find Id's query in a background thread. 809 * <p> 810 * This returns a Future object which can be used to cancel, check the 811 * execution status (isDone etc) and get the value (with or without a 812 * timeout). 813 * </p> 814 * 815 * @return a Future object for the list of Id's 816 */ 817 FutureIds<T> findFutureIds(); 818 819 /** 820 * Execute find list query in a background thread. 821 * <p> 822 * This query will execute in it's own PersistenceContext and using its own transaction. 823 * What that means is that it will not share any bean instances with other queries. 824 * </p> 825 * 826 * @return a Future object for the list result of the query 827 */ 828 FutureList<T> findFutureList(); 829 830 /** 831 * Return a PagedList for this query using firstRow and maxRows. 832 * <p> 833 * The benefit of using this over findList() is that it provides functionality to get the 834 * total row count etc. 835 * </p> 836 * <p> 837 * If maxRows is not set on the query prior to calling findPagedList() then a 838 * PersistenceException is thrown. 839 * </p> 840 * <pre>{@code 841 * 842 * PagedList<Order> pagedList = Ebean.find(Order.class) 843 * .setFirstRow(50) 844 * .setMaxRows(20) 845 * .findPagedList(); 846 * 847 * // fetch the total row count in the background 848 * pagedList.loadRowCount(); 849 * 850 * List<Order> orders = pagedList.getList(); 851 * int totalRowCount = pagedList.getTotalRowCount(); 852 * 853 * }</pre> 854 * 855 * @return The PagedList 856 */ 857 PagedList<T> findPagedList(); 858 859 /** 860 * Set a named bind parameter. Named parameters have a colon to prefix the name. 861 * <pre>{@code 862 * 863 * // a query with a named parameter 864 * String oql = "find order where status = :orderStatus"; 865 * 866 * Query<Order> query = ebeanServer.find(Order.class, oql); 867 * 868 * // bind the named parameter 869 * query.bind("orderStatus", OrderStatus.NEW); 870 * List<Order> list = query.findList(); 871 * 872 * }</pre> 873 * 874 * @param name the parameter name 875 * @param value the parameter value 876 */ 877 Query<T> setParameter(String name, Object value); 878 879 /** 880 * Set an ordered bind parameter according to its position. Note that the 881 * position starts at 1 to be consistent with JDBC PreparedStatement. You need 882 * to set a parameter value for each ? you have in the query. 883 * <pre>{@code 884 * 885 * // a query with a positioned parameter 886 * String oql = "where status = ? order by id desc"; 887 * 888 * Query<Order> query = ebeanServer.createQuery(Order.class, oql); 889 * 890 * // bind the parameter 891 * query.setParameter(1, OrderStatus.NEW); 892 * 893 * List<Order> list = query.findList(); 894 * 895 * }</pre> 896 * 897 * @param position the parameter bind position starting from 1 (not 0) 898 * @param value the parameter bind value. 899 */ 900 Query<T> setParameter(int position, Object value); 901 902 /** 903 * Set the Id value to query. This is used with findUnique(). 904 * <p> 905 * You can use this to have further control over the query. For example adding 906 * fetch joins. 907 * </p> 908 * <pre>{@code 909 * 910 * Order order = 911 * ebeanServer.find(Order.class) 912 * .setId(1) 913 * .fetch("details") 914 * .findUnique(); 915 * 916 * // the order details were eagerly fetched 917 * List<OrderDetail> details = order.getDetails(); 918 * 919 * }</pre> 920 */ 921 Query<T> setId(Object id); 922 923 /** 924 * Return the Id value. 925 */ 926 Object getId(); 927 928 /** 929 * Add a single Expression to the where clause returning the query. 930 * <pre>{@code 931 * 932 * List<Order> newOrders = 933 * ebeanServer.find(Order.class) 934 * .where().eq("status", Order.NEW) 935 * .findList(); 936 * ... 937 * 938 * }</pre> 939 */ 940 Query<T> where(Expression expression); 941 942 /** 943 * Add Expressions to the where clause with the ability to chain on the 944 * ExpressionList. You can use this for adding multiple expressions to the 945 * where clause. 946 * <pre>{@code 947 * 948 * List<Order> orders = 949 * ebeanServer.find(Order.class) 950 * .where() 951 * .eq("status", Order.NEW) 952 * .ilike("customer.name","rob%") 953 * .findList(); 954 * 955 * }</pre> 956 * 957 * @return The ExpressionList for adding expressions to. 958 * @see Expr 959 */ 960 ExpressionList<T> where(); 961 962 /** 963 * Add Full text search expressions for Document store queries. 964 * <p> 965 * This is currently ElasticSearch only and provides the full text 966 * expressions such as Match and Multi-Match. 967 * </p> 968 * <p> 969 * This automatically makes this query a "Doc Store" query and will execute 970 * against the document store (ElasticSearch). 971 * </p> 972 * <p> 973 * Expressions added here are added to the "query" section of an ElasticSearch 974 * query rather than the "filter" section. 975 * </p> 976 * <p> 977 * Expressions added to the where() are added to the "filter" section of an 978 * ElasticSearch query. 979 * </p> 980 */ 981 ExpressionList<T> text(); 982 983 /** 984 * This applies a filter on the 'many' property list rather than the root 985 * level objects. 986 * <p> 987 * Typically you will use this in a scenario where the cardinality is high on 988 * the 'many' property you wish to join to. Say you want to fetch customers 989 * and their associated orders... but instead of getting all the orders for 990 * each customer you only want to get the new orders they placed since last 991 * week. In this case you can use filterMany() to filter the orders. 992 * </p> 993 * <pre>{@code 994 * 995 * List<Customer> list = 996 * ebeanServer.find(Customer.class) 997 * // .fetch("orders", new FetchConfig().lazy()) 998 * // .fetch("orders", new FetchConfig().query()) 999 * .fetch("orders") 1000 * .where().ilike("name", "rob%") 1001 * .filterMany("orders").eq("status", Order.Status.NEW).gt("orderDate", lastWeek) 1002 * .findList(); 1003 * 1004 * }</pre> 1005 * <p> 1006 * Please note you have to be careful that you add expressions to the correct 1007 * expression list - as there is one for the 'root level' and one for each 1008 * filterMany that you have. 1009 * </p> 1010 * 1011 * @param propertyName the name of the many property that you want to have a filter on. 1012 * @return the expression list that you add filter expressions for the many 1013 * to. 1014 */ 1015 ExpressionList<T> filterMany(String propertyName); 1016 1017 /** 1018 * Add Expressions to the Having clause return the ExpressionList. 1019 * <p> 1020 * Currently only beans based on raw sql will use the having clause. 1021 * </p> 1022 * <p> 1023 * Note that this returns the ExpressionList (so you can add multiple 1024 * expressions to the query in a fluent API way). 1025 * </p> 1026 * 1027 * @return The ExpressionList for adding more expressions to. 1028 * @see Expr 1029 */ 1030 ExpressionList<T> having(); 1031 1032 /** 1033 * Add an expression to the having clause returning the query. 1034 * <p> 1035 * Currently only beans based on raw sql will use the having clause. 1036 * </p> 1037 * <p> 1038 * This is similar to {@link #having()} except it returns the query rather 1039 * than the ExpressionList. This is useful when you want to further specify 1040 * something on the query. 1041 * </p> 1042 * 1043 * @param addExpressionToHaving the expression to add to the having clause. 1044 * @return the Query object 1045 */ 1046 Query<T> having(Expression addExpressionToHaving); 1047 1048 /** 1049 * Set the order by clause replacing the existing order by clause if there is 1050 * one. 1051 * <p> 1052 * This follows SQL syntax using commas between each property with the 1053 * optional asc and desc keywords representing ascending and descending order 1054 * respectively. 1055 * </p> 1056 * <p> 1057 * This is EXACTLY the same as {@link #order(String)}. 1058 * </p> 1059 */ 1060 Query<T> orderBy(String orderByClause); 1061 1062 /** 1063 * Set the order by clause replacing the existing order by clause if there is 1064 * one. 1065 * <p> 1066 * This follows SQL syntax using commas between each property with the 1067 * optional asc and desc keywords representing ascending and descending order 1068 * respectively. 1069 * </p> 1070 * <p> 1071 * This is EXACTLY the same as {@link #orderBy(String)}. 1072 * </p> 1073 */ 1074 Query<T> order(String orderByClause); 1075 1076 /** 1077 * Return the OrderBy so that you can append an ascending or descending 1078 * property to the order by clause. 1079 * <p> 1080 * This will never return a null. If no order by clause exists then an 'empty' 1081 * OrderBy object is returned. 1082 * </p> 1083 * <p> 1084 * This is EXACTLY the same as {@link #orderBy()}. 1085 * </p> 1086 */ 1087 OrderBy<T> order(); 1088 1089 /** 1090 * Return the OrderBy so that you can append an ascending or descending 1091 * property to the order by clause. 1092 * <p> 1093 * This will never return a null. If no order by clause exists then an 'empty' 1094 * OrderBy object is returned. 1095 * </p> 1096 * <p> 1097 * This is EXACTLY the same as {@link #order()}. 1098 * </p> 1099 */ 1100 OrderBy<T> orderBy(); 1101 1102 /** 1103 * Set an OrderBy object to replace any existing OrderBy clause. 1104 * <p> 1105 * This is EXACTLY the same as {@link #setOrderBy(OrderBy)}. 1106 * </p> 1107 */ 1108 Query<T> setOrder(OrderBy<T> orderBy); 1109 1110 /** 1111 * Set an OrderBy object to replace any existing OrderBy clause. 1112 * <p> 1113 * This is EXACTLY the same as {@link #setOrder(OrderBy)}. 1114 * </p> 1115 */ 1116 Query<T> setOrderBy(OrderBy<T> orderBy); 1117 1118 /** 1119 * Set whether this query uses DISTINCT. 1120 * <p> 1121 * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that 1122 * generally ORM queries include the "id" property and this doesn't make sense for distinct queries. 1123 * </p> 1124 * <pre>{@code 1125 * 1126 * List<Customer> customers = 1127 * Ebean.find(Customer.class) 1128 * .setDistinct(true) 1129 * .select("name") 1130 * .findList(); 1131 * 1132 * }</pre> 1133 */ 1134 Query<T> setDistinct(boolean isDistinct); 1135 1136 /** 1137 * Return the first row value. 1138 */ 1139 int getFirstRow(); 1140 1141 /** 1142 * Set the first row to return for this query. 1143 * 1144 * @param firstRow the first row to include in the query result. 1145 */ 1146 Query<T> setFirstRow(int firstRow); 1147 1148 /** 1149 * Return the max rows for this query. 1150 */ 1151 int getMaxRows(); 1152 1153 /** 1154 * Set the maximum number of rows to return in the query. 1155 * 1156 * @param maxRows the maximum number of rows to return in the query. 1157 */ 1158 Query<T> setMaxRows(int maxRows); 1159 1160 /** 1161 * Set the property to use as keys for a map. 1162 * <p> 1163 * If no property is set then the id property is used. 1164 * </p> 1165 * <pre>{@code 1166 * 1167 * // Assuming sku is unique for products... 1168 * 1169 * Map<?,Product> productMap = 1170 * ebeanServer.find(Product.class) 1171 * // use sku for keys... 1172 * .setMapKey("sku") 1173 * .findMap(); 1174 * 1175 * }</pre> 1176 * 1177 * @param mapKey the property to use as keys for a map. 1178 */ 1179 Query<T> setMapKey(String mapKey); 1180 1181 /** 1182 * Set this to false to not use the bean cache. 1183 * <p> 1184 * By default "find by id" and "find by natural key" will use the bean cache 1185 * when bean caching is enabled. Setting this to false means that the query 1186 * will not use the bean cache and instead hit the database. 1187 * </p> 1188 * <p> 1189 * In the case of other queries (findList(), findEach() etc) then setting this to 1190 * false beans that the if lazy loading is invoked that lazy loading will not try 1191 * to use the bean cache. 1192 * </p> 1193 */ 1194 Query<T> setUseCache(boolean useCache); 1195 1196 /** 1197 * Set this to true to use the query cache. 1198 */ 1199 Query<T> setUseQueryCache(boolean useQueryCache); 1200 1201 /** 1202 * Set to true if this query should execute against the doc store. 1203 * <p> 1204 * When setting this you may also consider disabling lazy loading. 1205 * </p> 1206 */ 1207 Query<T> setUseDocStore(boolean useDocStore); 1208 1209 /** 1210 * When set to true when you want the returned beans to be read only. 1211 */ 1212 Query<T> setReadOnly(boolean readOnly); 1213 1214 /** 1215 * When set to true all the beans from this query are loaded into the bean 1216 * cache. 1217 */ 1218 Query<T> setLoadBeanCache(boolean loadBeanCache); 1219 1220 /** 1221 * Set a timeout on this query. 1222 * <p> 1223 * This will typically result in a call to setQueryTimeout() on a 1224 * preparedStatement. If the timeout occurs an exception will be thrown - this 1225 * will be a SQLException wrapped up in a PersistenceException. 1226 * </p> 1227 * 1228 * @param secs the query timeout limit in seconds. Zero means there is no limit. 1229 */ 1230 Query<T> setTimeout(int secs); 1231 1232 /** 1233 * A hint which for JDBC translates to the Statement.fetchSize(). 1234 * <p> 1235 * Gives the JDBC driver a hint as to the number of rows that should be 1236 * fetched from the database when more rows are needed for ResultSet. 1237 * </p> 1238 * <p> 1239 * Note that internally findEach and findEachWhile will set the fetch size 1240 * if it has not already as these queries expect to process a lot of rows. 1241 * If we didn't then Postgres and MySql for example would eagerly pull back 1242 * all the row data and potentially consume a lot of memory in the process. 1243 * </p> 1244 * <p> 1245 * As findEach and findEachWhile automatically set the fetch size we don't have 1246 * to do so generally but we might still wish to for tuning a specific use case. 1247 * </p> 1248 */ 1249 Query<T> setBufferFetchSizeHint(int fetchSize); 1250 1251 /** 1252 * Return the sql that was generated for executing this query. 1253 * <p> 1254 * This is only available after the query has been executed and provided only 1255 * for informational purposes. 1256 * </p> 1257 */ 1258 String getGeneratedSql(); 1259 1260 /** 1261 * executed the select with "for update" which should lock the record 1262 * "on read" 1263 */ 1264 Query<T> setForUpdate(boolean forUpdate); 1265 1266 /** 1267 * Return true if this query has forUpdate set. 1268 */ 1269 boolean isForUpdate(); 1270 1271 /** 1272 * Set root table alias. 1273 */ 1274 Query<T> alias(String alias); 1275 1276 /** 1277 * Return the type of beans being queried. 1278 */ 1279 Class<T> getBeanType(); 1280 1281 /** 1282 * Set true if you want to disable lazy loading. 1283 * <p> 1284 * That is, once the object graph is returned further lazy loading is disabled. 1285 * </p> 1286 */ 1287 Query<T> setDisableLazyLoading(boolean disableLazyLoading); 1288 1289 /** 1290 * Returns the set of properties or paths that are unknown (do not map to known properties or paths). 1291 * <p> 1292 * Validate the query checking the where and orderBy expression paths to confirm if 1293 * they represent valid properties or paths for the given bean type. 1294 * </p> 1295 */ 1296 Set<String> validate(); 1297 1298}