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