001package com.avaje.ebean; 002 003import com.avaje.ebean.search.Match; 004import com.avaje.ebean.search.MultiMatch; 005import com.avaje.ebean.search.TextCommonTerms; 006import com.avaje.ebean.search.TextQueryString; 007import com.avaje.ebean.search.TextSimple; 008import org.jetbrains.annotations.Nullable; 009 010import javax.persistence.NonUniqueResultException; 011import java.sql.Timestamp; 012import java.util.Collection; 013import java.util.List; 014import java.util.Map; 015import java.util.Set; 016 017/** 018 * List of Expressions that make up a where or having clause. 019 * <p> 020 * An ExpressionList is returned from {@link Query#where()}. 021 * </p> 022 * <p> 023 * The ExpressionList has a list of convenience methods that create the standard 024 * expressions and add them to this list. 025 * </p> 026 * <p> 027 * The ExpressionList also duplicates methods that are found on the Query such 028 * as findList() and orderBy(). The purpose of these methods is provide a fluid 029 * API. The upside of this approach is that you can build and execute a query 030 * via chained methods. The down side is that this ExpressionList object has 031 * more methods than you would initially expect (the ones duplicated from 032 * Query). 033 * </p> 034 * 035 * @see Query#where() 036 */ 037public interface ExpressionList<T> { 038 039 /** 040 * Return the query that owns this expression list. 041 * <p> 042 * This is a convenience method solely to support a fluid API where the 043 * methods are chained together. Adding expressions returns this expression 044 * list and this method can be used after that to return back the original 045 * query so that further things can be added to it. 046 * </p> 047 */ 048 Query<T> query(); 049 050 /** 051 * Set the order by clause replacing the existing order by clause if there is 052 * one. 053 * <p> 054 * This follows SQL syntax using commas between each property with the 055 * optional asc and desc keywords representing ascending and descending order 056 * respectively. 057 * </p> 058 * <p> 059 * This is EXACTLY the same as {@link #orderBy(String)}. 060 * </p> 061 */ 062 Query<T> order(String orderByClause); 063 064 /** 065 * Return the OrderBy so that you can append an ascending or descending 066 * property to the order by clause. 067 * <p> 068 * This will never return a null. If no order by clause exists then an 'empty' 069 * OrderBy object is returned. 070 * </p> 071 */ 072 OrderBy<T> order(); 073 074 /** 075 * Return the OrderBy so that you can append an ascending or descending 076 * property to the order by clause. 077 * <p> 078 * This will never return a null. If no order by clause exists then an 'empty' 079 * OrderBy object is returned. 080 * </p> 081 */ 082 OrderBy<T> orderBy(); 083 084 /** 085 * Add an orderBy clause to the query. 086 * 087 * @see Query#orderBy(String) 088 */ 089 Query<T> orderBy(String orderBy); 090 091 /** 092 * Add an orderBy clause to the query. 093 * 094 * @see Query#orderBy(String) 095 */ 096 Query<T> setOrderBy(String orderBy); 097 098 /** 099 * Apply the path properties to the query replacing the select and fetch clauses. 100 */ 101 Query<T> apply(FetchPath fetchPath); 102 103 /** 104 * Perform an 'As of' query using history tables to return the object graph 105 * as of a time in the past. 106 * <p> 107 * To perform this query the DB must have underlying history tables. 108 * </p> 109 * 110 * @param asOf the date time in the past at which you want to view the data 111 */ 112 Query<T> asOf(Timestamp asOf); 113 114 /** 115 * Execute the query against the draft set of tables. 116 */ 117 Query<T> asDraft(); 118 119 /** 120 * Execute the query including soft deleted rows. 121 */ 122 Query<T> includeSoftDeletes(); 123 124 /** 125 * Execute as a delete query deleting the 'root level' beans that match the predicates 126 * in the query. 127 * <p> 128 * Note that if the query includes joins then the generated delete statement may not be 129 * optimal depending on the database platform. 130 * </p> 131 * 132 * @return the number of beans/rows that were deleted. 133 */ 134 int delete(); 135 136 /** 137 * Execute the query iterating over the results. 138 * 139 * @see Query#findIterate() 140 */ 141 QueryIterator<T> findIterate(); 142 143 /** 144 * Execute the query process the beans one at a time. 145 * 146 * @see Query#findEach(QueryEachConsumer) 147 */ 148 void findEach(QueryEachConsumer<T> consumer); 149 150 /** 151 * Execute the query processing the beans one at a time with the ability to 152 * stop processing before reading all the beans. 153 * 154 * @see Query#findEachWhile(QueryEachWhileConsumer) 155 */ 156 void findEachWhile(QueryEachWhileConsumer<T> consumer); 157 158 /** 159 * Execute the query returning a list. 160 * 161 * @see Query#findList() 162 */ 163 List<T> findList(); 164 165 /** 166 * Execute the query returning the list of Id's. 167 * 168 * @see Query#findIds() 169 */ 170 List<Object> findIds(); 171 172 /** 173 * Return the count of entities this query should return. 174 * <p> 175 * This is the number of 'top level' or 'root level' entities. 176 * </p> 177 */ 178 int findRowCount(); 179 180 /** 181 * Execute the query returning a set. 182 * 183 * @see Query#findSet() 184 */ 185 Set<T> findSet(); 186 187 /** 188 * Execute the query returning a map. 189 * 190 * @see Query#findMap() 191 */ 192 Map<?, T> findMap(); 193 194 /** 195 * Return a typed map specifying the key property and type. 196 */ 197 <K> Map<K, T> findMap(String keyProperty, Class<K> keyType); 198 199 /** 200 * Execute the query returning a single bean or null (if no matching 201 * bean is found). 202 * <p> 203 * If more than 1 row is found for this query then a NonUniqueResultException is 204 * thrown. 205 * </p> 206 * 207 * @throws NonUniqueResultException if more than one result was found 208 * 209 * @see Query#findUnique() 210 */ 211 @Nullable 212 T findUnique(); 213 214 /** 215 * Execute find row count query in a background thread. 216 * <p> 217 * This returns a Future object which can be used to cancel, check the 218 * execution status (isDone etc) and get the value (with or without a 219 * timeout). 220 * </p> 221 * 222 * @return a Future object for the row count query 223 */ 224 FutureRowCount<T> findFutureRowCount(); 225 226 /** 227 * Execute find Id's query in a background thread. 228 * <p> 229 * This returns a Future object which can be used to cancel, check the 230 * execution status (isDone etc) and get the value (with or without a 231 * timeout). 232 * </p> 233 * 234 * @return a Future object for the list of Id's 235 */ 236 FutureIds<T> findFutureIds(); 237 238 /** 239 * Execute find list query in a background thread. 240 * <p> 241 * This returns a Future object which can be used to cancel, check the 242 * execution status (isDone etc) and get the value (with or without a 243 * timeout). 244 * </p> 245 * 246 * @return a Future object for the list result of the query 247 */ 248 FutureList<T> findFutureList(); 249 250 /** 251 * Return a PagedList for this query using pageIndex and pageSize. 252 * <p> 253 * The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and 254 * {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to 255 * {@link Query#findFutureRowCount()} to determine total row count, total page count etc. 256 * </p> 257 * <p> 258 * Internally this works using {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} on 259 * the query. This translates into SQL that uses limit offset, rownum or row_number 260 * function to limit the result set. 261 * </p> 262 * 263 * @param pageIndex 264 * The zero based index of the page. 265 * @param pageSize 266 * The number of beans to return per page. 267 * @return The PagedList 268 */ 269 PagedList<T> findPagedList(int pageIndex, int pageSize); 270 271 /** 272 * Return a PagedList for this query using firstRow and maxRows. 273 * <p> 274 * The benefit of using this over findList() is that it provides functionality to get the 275 * total row count etc. 276 * </p> 277 * <p> 278 * If maxRows is not set on the query prior to calling findPagedList() then a 279 * PersistenceException is thrown. 280 * </p> 281 * 282 * <pre>{@code 283 * 284 * PagedList<Order> pagedList = Ebean.find(Order.class) 285 * .setFirstRow(50) 286 * .setMaxRows(20) 287 * .findPagedList(); 288 * 289 * // fetch the total row count in the background 290 * pagedList.loadRowCount(); 291 * 292 * List<Order> orders = pagedList.getList(); 293 * int totalRowCount = pagedList.getTotalRowCount(); 294 * 295 * }</pre> 296 * 297 * @return The PagedList 298 * 299 * @see Query#findPagedList() 300 */ 301 PagedList<T> findPagedList(); 302 303 /** 304 * Return versions of a @History entity bean. 305 * <p> 306 * Generally this query is expected to be a find by id or unique predicates query. 307 * It will execute the query against the history returning the versions of the bean. 308 * </p> 309 */ 310 List<Version<T>> findVersions(); 311 312 /** 313 * Return versions of a @History entity bean between the 2 timestamps. 314 * <p> 315 * Generally this query is expected to be a find by id or unique predicates query. 316 * It will execute the query against the history returning the versions of the bean. 317 * </p> 318 */ 319 List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end); 320 321 /** 322 * Add some filter predicate expressions to the many property. 323 */ 324 ExpressionList<T> filterMany(String prop); 325 326 /** 327 * Specify specific properties to fetch on the main/root bean (aka partial 328 * object). 329 * 330 * @see Query#select(String) 331 */ 332 Query<T> select(String properties); 333 334 /** 335 * Set whether this query uses DISTINCT. 336 * <p> 337 * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that 338 * generally ORM queries include the "id" property and this doesn't make sense for distinct queries. 339 * </p> 340 * <pre>{@code 341 * 342 * List<Customer> customers = 343 * Ebean.find(Customer.class) 344 * .setDistinct(true) 345 * .select("name") // only select the customer name 346 * .findList(); 347 * 348 * }</pre> 349 */ 350 Query<T> setDistinct(boolean distinct); 351 352 /** 353 * Set the first row to fetch. 354 * 355 * @see Query#setFirstRow(int) 356 */ 357 Query<T> setFirstRow(int firstRow); 358 359 /** 360 * Set the maximum number of rows to fetch. 361 * 362 * @see Query#setMaxRows(int) 363 */ 364 Query<T> setMaxRows(int maxRows); 365 366 /** 367 * Set the name of the property which values become the key of a map. 368 * 369 * @see Query#setMapKey(String) 370 */ 371 Query<T> setMapKey(String mapKey); 372 373 /** 374 * Set to true to use the query for executing this query. 375 * 376 * @see Query#setUseCache(boolean) 377 */ 378 Query<T> setUseCache(boolean useCache); 379 380 /** 381 * Set to true to use the query for executing this query. 382 * 383 * @see Query#setUseQueryCache(boolean) 384 */ 385 Query<T> setUseQueryCache(boolean useCache); 386 387 /** 388 * Set to true if this query should execute against the doc store. 389 * <p> 390 * When setting this you may also consider disabling lazy loading. 391 * </p> 392 */ 393 Query<T> setUseDocStore(boolean useDocsStore); 394 395 /** 396 * Set true if you want to disable lazy loading. 397 * <p> 398 * That is, once the object graph is returned further lazy loading is disabled. 399 * </p> 400 */ 401 Query<T> setDisableLazyLoading(boolean disableLazyLoading); 402 403 /** 404 * Disable read auditing for this query. 405 * <p> 406 * This is intended to be used when the query is not a user initiated query and instead 407 * part of the internal processing in an application to load a cache or document store etc. 408 * In these cases we don't want the query to be part of read auditing. 409 * </p> 410 */ 411 Query<T> setDisableReadAuditing(); 412 413 /** 414 * Add expressions to the having clause. 415 * <p> 416 * The having clause is only used for queries based on raw sql (via SqlSelect 417 * annotation etc). 418 * </p> 419 */ 420 ExpressionList<T> having(); 421 422 /** 423 * Add another expression to the where clause. 424 */ 425 ExpressionList<T> where(); 426 427 /** 428 * Path exists - for the given path in a JSON document. 429 * 430 * <pre>{@code 431 * 432 * where().jsonExists("content", "path.other") 433 * 434 * }</pre> 435 * 436 * @param propertyName the property that holds a JSON document 437 * @param path the nested path in the JSON document in dot notation 438 */ 439 ExpressionList<T> jsonExists(String propertyName, String path); 440 441 /** 442 * Path does not exist - for the given path in a JSON document. 443 * 444 * <pre>{@code 445 * 446 * where().jsonNotExists("content", "path.other") 447 * 448 * }</pre> 449 * 450 * @param propertyName the property that holds a JSON document 451 * @param path the nested path in the JSON document in dot notation 452 */ 453 ExpressionList<T> jsonNotExists(String propertyName, String path); 454 455 /** 456 * Equal to expression for the value at the given path in the JSON document. 457 * 458 * <pre>{@code 459 * 460 * where().jsonEqualTo("content", "path.other", 34) 461 * 462 * }</pre> 463 * 464 * @param propertyName the property that holds a JSON document 465 * @param path the nested path in the JSON document in dot notation 466 * @param value the value used to test against the document path's value 467 */ 468 ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value); 469 470 /** 471 * Not Equal to - for the given path in a JSON document. 472 * 473 * <pre>{@code 474 * 475 * where().jsonNotEqualTo("content", "path.other", 34) 476 * 477 * }</pre> 478 * 479 * @param propertyName the property that holds a JSON document 480 * @param path the nested path in the JSON document in dot notation 481 * @param value the value used to test against the document path's value 482 */ 483 ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object value); 484 485 /** 486 * Greater than - for the given path in a JSON document. 487 * 488 * <pre>{@code 489 * 490 * where().jsonGreaterThan("content", "path.other", 34) 491 * 492 * }</pre> 493 */ 494 ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object value); 495 496 /** 497 * Greater than or equal to - for the given path in a JSON document. 498 * 499 * <pre>{@code 500 * 501 * where().jsonGreaterOrEqual("content", "path.other", 34) 502 * 503 * }</pre> 504 */ 505 ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object value); 506 507 /** 508 * Less than - for the given path in a JSON document. 509 * 510 * <pre>{@code 511 * 512 * where().jsonLessThan("content", "path.other", 34) 513 * 514 * }</pre> 515 */ 516 ExpressionList<T> jsonLessThan(String propertyName, String path, Object value); 517 518 /** 519 * Less than or equal to - for the given path in a JSON document. 520 * 521 * <pre>{@code 522 * 523 * where().jsonLessOrEqualTo("content", "path.other", 34) 524 * 525 * }</pre> 526 */ 527 ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object value); 528 529 /** 530 * Between - for the given path in a JSON document. 531 * 532 * <pre>{@code 533 * 534 * where().jsonBetween("content", "orderDate", lowerDateTime, upperDateTime) 535 * 536 * }</pre> 537 */ 538 ExpressionList<T> jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue); 539 540 /** 541 * Add an Expression to the list. 542 * <p> 543 * This returns the list so that add() can be chained. 544 * </p> 545 * 546 * <pre>{@code 547 * 548 * Query<Customer> query = Ebean.find(Customer.class); 549 * query.where() 550 * .like("name","Rob%") 551 * .eq("status", Customer.ACTIVE); 552 * 553 * List<Customer> list = query.findList(); 554 * ... 555 * 556 * }</pre> 557 */ 558 ExpressionList<T> add(Expression expr); 559 560 /** 561 * Add a list of Expressions to this ExpressionList.s 562 */ 563 ExpressionList<T> addAll(ExpressionList<T> exprList); 564 565 /** 566 * Equal To - property is equal to a given value. 567 */ 568 ExpressionList<T> eq(String propertyName, Object value); 569 570 /** 571 * Not Equal To - property not equal to the given value. 572 */ 573 ExpressionList<T> ne(String propertyName, Object value); 574 575 /** 576 * Case Insensitive Equal To - property equal to the given value (typically 577 * using a lower() function to make it case insensitive). 578 */ 579 ExpressionList<T> ieq(String propertyName, String value); 580 581 /** 582 * Between - property between the two given values. 583 */ 584 ExpressionList<T> between(String propertyName, Object value1, Object value2); 585 586 /** 587 * Between - value between the two properties. 588 */ 589 ExpressionList<T> betweenProperties(String lowProperty, String highProperty, Object value); 590 591 /** 592 * Greater Than - property greater than the given value. 593 */ 594 ExpressionList<T> gt(String propertyName, Object value); 595 596 /** 597 * Greater Than or Equal to - property greater than or equal to the given 598 * value. 599 */ 600 ExpressionList<T> ge(String propertyName, Object value); 601 602 /** 603 * Less Than - property less than the given value. 604 */ 605 ExpressionList<T> lt(String propertyName, Object value); 606 607 /** 608 * Less Than or Equal to - property less than or equal to the given value. 609 */ 610 ExpressionList<T> le(String propertyName, Object value); 611 612 /** 613 * Is Null - property is null. 614 */ 615 ExpressionList<T> isNull(String propertyName); 616 617 /** 618 * Is Not Null - property is not null. 619 */ 620 ExpressionList<T> isNotNull(String propertyName); 621 622 /** 623 * A "Query By Example" type of expression. 624 * <p> 625 * Pass in an example entity and for each non-null scalar properties an 626 * expression is added. 627 * </p> 628 * <p> 629 * By Default this case sensitive, will ignore numeric zero values and will 630 * use a Like for string values (you must put in your own wildcards). 631 * </p> 632 * <p> 633 * To get control over the options you can create an ExampleExpression and set 634 * those options such as case insensitive etc. 635 * </p> 636 * 637 * <pre>{@code 638 * 639 * // create an example bean and set the properties 640 * // with the query parameters you want 641 * Customer example = new Customer(); 642 * example.setName("Rob%"); 643 * example.setNotes("%something%"); 644 * 645 * List<Customer> list = Ebean.find(Customer.class).where() 646 * // pass the bean into the where() clause 647 * .exampleLike(example) 648 * // you can add other expressions to the same query 649 * .gt("id", 2).findList(); 650 * 651 * }</pre> 652 * 653 * Similarly you can create an ExampleExpression 654 * 655 * <pre>{@code 656 * 657 * Customer example = new Customer(); 658 * example.setName("Rob%"); 659 * example.setNotes("%something%"); 660 * 661 * // create a ExampleExpression with more control 662 * ExampleExpression qbe = new ExampleExpression(example, true, LikeType.EQUAL_TO).includeZeros(); 663 * 664 * List<Customer> list = Ebean.find(Customer.class).where().add(qbe).findList(); 665 * 666 * }</pre> 667 */ 668 ExpressionList<T> exampleLike(Object example); 669 670 /** 671 * Case insensitive version of {@link #exampleLike(Object)} 672 */ 673 ExpressionList<T> iexampleLike(Object example); 674 675 /** 676 * Like - property like value where the value contains the SQL wild card 677 * characters % (percentage) and _ (underscore). 678 */ 679 ExpressionList<T> like(String propertyName, String value); 680 681 /** 682 * Case insensitive Like - property like value where the value contains the 683 * SQL wild card characters % (percentage) and _ (underscore). Typically uses 684 * a lower() function to make the expression case insensitive. 685 */ 686 ExpressionList<T> ilike(String propertyName, String value); 687 688 /** 689 * Starts With - property like value%. 690 */ 691 ExpressionList<T> startsWith(String propertyName, String value); 692 693 /** 694 * Case insensitive Starts With - property like value%. Typically uses a 695 * lower() function to make the expression case insensitive. 696 */ 697 ExpressionList<T> istartsWith(String propertyName, String value); 698 699 /** 700 * Ends With - property like %value. 701 */ 702 ExpressionList<T> endsWith(String propertyName, String value); 703 704 /** 705 * Case insensitive Ends With - property like %value. Typically uses a lower() 706 * function to make the expression case insensitive. 707 */ 708 ExpressionList<T> iendsWith(String propertyName, String value); 709 710 /** 711 * Contains - property like %value%. 712 */ 713 ExpressionList<T> contains(String propertyName, String value); 714 715 /** 716 * Case insensitive Contains - property like %value%. Typically uses a lower() 717 * function to make the expression case insensitive. 718 */ 719 ExpressionList<T> icontains(String propertyName, String value); 720 721 /** 722 * In - using a subQuery. 723 */ 724 ExpressionList<T> in(String propertyName, Query<?> subQuery); 725 726 /** 727 * In - property has a value in the array of values. 728 */ 729 ExpressionList<T> in(String propertyName, Object... values); 730 731 /** 732 * In - property has a value in the collection of values. 733 */ 734 ExpressionList<T> in(String propertyName, Collection<?> values); 735 736 /** 737 * Not In - property has a value in the array of values. 738 */ 739 ExpressionList<T> notIn(String propertyName, Object... values); 740 741 /** 742 * Not In - property has a value in the collection of values. 743 */ 744 ExpressionList<T> notIn(String propertyName, Collection<?> values); 745 746 /** 747 * Not In - using a subQuery. 748 */ 749 ExpressionList<T> notIn(String propertyName, Query<?> subQuery); 750 751 /** 752 * Exists expression 753 */ 754 ExpressionList<T> exists(Query<?> subQuery); 755 756 /** 757 * Not exists expression 758 */ 759 ExpressionList<T> notExists(Query<?> subQuery); 760 761 /** 762 * Id IN a list of id values. 763 */ 764 ExpressionList<T> idIn(List<?> idValues); 765 766 /** 767 * Id Equal to - ID property is equal to the value. 768 */ 769 ExpressionList<T> idEq(Object value); 770 771 /** 772 * All Equal - Map containing property names and their values. 773 * <p> 774 * Expression where all the property names in the map are equal to the 775 * corresponding value. 776 * </p> 777 * 778 * @param propertyMap 779 * a map keyed by property names. 780 */ 781 ExpressionList<T> allEq(Map<String, Object> propertyMap); 782 783 /** 784 * Add raw expression with a single parameter. 785 * <p> 786 * The raw expression should contain a single ? at the location of the 787 * parameter. 788 * </p> 789 * <p> 790 * When properties in the clause are fully qualified as table-column names 791 * then they are not translated. logical property name names (not fully 792 * qualified) will still be translated to their physical name. 793 * </p> 794 * 795 * <h4>Example:</h4> 796 * <pre>{@code 797 * 798 * // use a database function 799 * raw("add_days(orderDate, 10) < ?", someDate) 800 * 801 * }</pre> 802 */ 803 ExpressionList<T> raw(String raw, Object value); 804 805 /** 806 * Add raw expression with an array of parameters. 807 * <p> 808 * The raw expression should contain the same number of ? as there are 809 * parameters. 810 * </p> 811 * <p> 812 * When properties in the clause are fully qualified as table-column names 813 * then they are not translated. logical property name names (not fully 814 * qualified) will still be translated to their physical name. 815 * </p> 816 */ 817 ExpressionList<T> raw(String raw, Object... values); 818 819 /** 820 * Add raw expression with no parameters. 821 * <p> 822 * When properties in the clause are fully qualified as table-column names 823 * then they are not translated. logical property name names (not fully 824 * qualified) will still be translated to their physical name. 825 * </p> 826 * 827 * <pre>{@code 828 * 829 * raw("orderQty < shipQty") 830 * 831 * }</pre> 832 */ 833 ExpressionList<T> raw(String raw); 834 835 /** 836 * Add a match expression. 837 * 838 * @param propertyName The property name for the match 839 * @param search The search value 840 */ 841 ExpressionList<T> match(String propertyName, String search); 842 843 /** 844 * Add a match expression with options. 845 * 846 * @param propertyName The property name for the match 847 * @param search The search value 848 */ 849 ExpressionList<T> match(String propertyName, String search, Match options); 850 851 /** 852 * Add a multi-match expression. 853 */ 854 ExpressionList<T> multiMatch(String search, String... properties); 855 856 /** 857 * Add a multi-match expression using options. 858 */ 859 ExpressionList<T> multiMatch(String search, MultiMatch options); 860 861 /** 862 * Add a simple query string expression. 863 */ 864 ExpressionList<T> textSimple(String search, TextSimple options); 865 866 /** 867 * Add a query string expression. 868 */ 869 ExpressionList<T> textQueryString(String search, TextQueryString options); 870 871 /** 872 * Add common terms expression. 873 */ 874 ExpressionList<T> textCommonTerms(String search, TextCommonTerms options); 875 876 /** 877 * And - join two expressions with a logical and. 878 */ 879 ExpressionList<T> and(Expression expOne, Expression expTwo); 880 881 /** 882 * Or - join two expressions with a logical or. 883 */ 884 ExpressionList<T> or(Expression expOne, Expression expTwo); 885 886 /** 887 * Negate the expression (prefix it with NOT). 888 */ 889 ExpressionList<T> not(Expression exp); 890 891 /** 892 * Start a list of expressions that will be joined by AND's 893 * returning the expression list the expressions are added to. 894 * <p> 895 * This is exactly the same as conjunction(); 896 * </p> 897 * <p> 898 * Use endJunction() to end the AND junction. 899 * </p> 900 * <p> 901 * Note that a where() clause defaults to an AND junction so 902 * typically you only explicitly need to use the and() junction 903 * when it is nested inside an or() or not() junction. 904 * </p> 905 * 906 * <pre>{@code 907 * 908 * // Example: Nested and() 909 * 910 * Ebean.find(Customer.class) 911 * .where() 912 * .or() 913 * .and() // nested and 914 * .startsWith("name", "r") 915 * .eq("anniversary", onAfter) 916 * .endJunction() // end AND junction 917 * .and() 918 * .eq("status", Customer.Status.ACTIVE) 919 * .gt("id", 0) 920 * .endJunction() // end AND junction 921 * .orderBy().asc("name") 922 * .findList(); 923 * }</pre> 924 */ 925 Junction<T> and(); 926 927 /** 928 * Return a list of expressions that will be joined by OR's. 929 * This is exactly the same as disjunction(); 930 * 931 * <p> 932 * Use endJunction() to end the OR junction. 933 * </p> 934 * 935 * <pre>{@code 936 * 937 * // Example: Use or() to join 938 * // two nested and() expressions 939 * 940 * Ebean.find(Customer.class) 941 * .where() 942 * .or() 943 * .and() 944 * .startsWith("name", "r") 945 * .eq("anniversary", onAfter) 946 * .endJunction() // end AND junction 947 * .and() 948 * .eq("status", Customer.Status.ACTIVE) 949 * .gt("id", 0) 950 * .endJunction() // end AND junction 951 * .orderBy().asc("name") 952 * .findList(); 953 * 954 * }</pre> 955 */ 956 Junction<T> or(); 957 958 /** 959 * Return a list of expressions that will be wrapped by NOT. 960 * <p> 961 * Use endJunction() to end expressions being added to the 962 * NOT expression list. 963 * </p> 964 * 965 * <pre>@{code 966 * 967 * .where() 968 * .not() 969 * .gt("id", 1) 970 * .eq("anniversary", onAfter) 971 * .endJunction() // end the not expressions 972 * 973 * }</pre> 974 * 975 * <pre>@{code 976 * 977 * // Example: nested not() 978 * 979 * Ebean.find(Customer.class) 980 * .where() 981 * .eq("status", Customer.Status.ACTIVE) 982 * .not() 983 * .gt("id", 1) 984 * .eq("anniversary", onAfter) 985 * .endJunction() // end the not expressions 986 * .orderBy() 987 * .asc("name") 988 * .findList(); 989 * 990 * }</pre> 991 */ 992 Junction<T> not(); 993 994 /** 995 * Start (and return) a list of expressions that will be joined by AND's. 996 * <p> 997 * This is the same as and(). 998 * </p> 999 */ 1000 Junction<T> conjunction(); 1001 1002 /** 1003 * Start (and return) a list of expressions that will be joined by OR's. 1004 * <p> 1005 * This is the same as or(). 1006 * </p> 1007 */ 1008 Junction<T> disjunction(); 1009 1010 /** 1011 * Start a list of expressions that will be joined by MUST. 1012 * <p> 1013 * This automatically makes the query a useDocStore(true) query that 1014 * will execute against the document store (ElasticSearch etc). 1015 * </p> 1016 * <p> 1017 * This is logically similar to and(). 1018 * </p> 1019 */ 1020 Junction<T> must(); 1021 1022 /** 1023 * Start a list of expressions that will be joined by SHOULD. 1024 * <p> 1025 * This automatically makes the query a useDocStore(true) query that 1026 * will execute against the document store (ElasticSearch etc). 1027 * </p> 1028 * <p> 1029 * This is logically similar to or(). 1030 * </p> 1031 */ 1032 Junction<T> should(); 1033 1034 /** 1035 * Start a list of expressions that will be joined by MUST NOT. 1036 * <p> 1037 * This automatically makes the query a useDocStore(true) query that 1038 * will execute against the document store (ElasticSearch etc). 1039 * </p> 1040 * <p> 1041 * This is logically similar to not(). 1042 * </p> 1043 */ 1044 Junction<T> mustNot(); 1045 1046 /** 1047 * End a junction returning the parent expression list. 1048 * <p> 1049 * Ends a and(), or(), not(), must(), mustNot() or should() junction 1050 * such that you get the parent expression. 1051 * </p> 1052 * <p> 1053 * Alternatively you can always use where() to return the top level expression list. 1054 * </p> 1055 */ 1056 ExpressionList<T> endJunction(); 1057 1058}