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