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