001package io.ebean;
002
003import javax.annotation.Nonnull;
004
005/**
006 * Defines what part of the object graph to load (select and fetch clauses).
007 * <p>
008 * Using a FetchGroup effectively sets the select() and fetch() clauses for a query. It is alternative
009 * to specifying the select() and fetch() clauses on the query allowing for more re-use of "what to load"
010 * that can be defined separately from the query and combined with other FetchGroups.
011 * </p>
012 *
013 * <h3>Select example</h3>
014 * <pre>{@code
015 *
016 * FetchGroup<Customer> fetchGroup = FetchGroup.of(Customer.class, "name, status");
017 *
018 * Customer.query()
019 *   .select(fetchGroup)
020 *   .findList();
021 *
022 * }</pre>
023 *
024 * <h3>Select and fetch example</h3>
025 * <pre>{@code
026 *
027 * FetchGroup<Customer> fetchGroup = FetchGroup.of(Customer.class)
028 *   .select("name, status")
029 *   .fetch("contacts", "firstName, lastName, email")
030 *   .build();
031 *
032 * Customer.query()
033 *   .select(fetchGroup)
034 *   .findList();
035 *
036 * }</pre>
037 *
038 * <h3>Combining FetchGroups</h3>
039 * <p>
040 *   FetchGroups can be combined together to form another FetchGroup.
041 * </p>
042 * <pre>{@code
043 *
044 *  FetchGroup<Address> FG_ADDRESS = FetchGroup.of(Address.class)
045 *    .select("line1, line2, city")
046 *    .fetch("country", "name")
047 *    .build();
048 *
049 *  FetchGroup<Customer> FG_CUSTOMER = FetchGroup.of(Customer.class)
050 *    .select("name, version")
051 *    .fetch("billingAddress", FG_ADDRESS)
052 *    .build();
053 *
054 *
055 *  Customer.query()
056 *    .select(FG_CUSTOMER)
057 *    .findList();
058 *
059 * }</pre>
060 *
061 * @param <T> The bean type the Fetch group can be applied to
062 */
063public interface FetchGroup<T> {
064
065  /**
066   * Return the FetchGroup with the given select clause.
067   * <p>
068   *   We use this for simple FetchGroup that only select() properties and do not have additional fetch() clause.
069   * </p>
070   * <pre>{@code
071   *
072   * FetchGroup<Customer> fetchGroup = FetchGroup.of(Customer.class, "name, status");
073   *
074   * Customer.query()
075   *   .select(fetchGroup)
076   *   .findList();
077   *
078   * }</pre>
079   *
080   * @param select The select clause of the FetchGroup
081   *
082   * @return The FetchGroup with the given select clause
083   */
084  @Nonnull
085  static <T> FetchGroup<T> of(Class<T> cls, String select) {
086    return XServiceProvider.fetchGroupOf(cls, select);
087  }
088
089  /**
090   * Return the FetchGroupBuilder with the given select clause that we can add fetch clauses to.
091   * <p>
092   * We chain select() with one or more fetch() clauses to define the object graph to load.
093   * </p>
094   * <pre>{@code
095   *
096   * FetchGroup<Customer> fetchGroup = FetchGroup.of(Customer.class)
097   *   .select("name, status")
098   *   .fetch("contacts", "firstName, lastName, email")
099   *   .build();
100   *
101   * Customer.query()
102   *   .select(fetchGroup)
103   *   .findList();
104   *
105   * }</pre>
106   *
107   * @return The FetchGroupBuilder with the given select clause which we will add fetch clauses to
108   */
109  @Nonnull
110  static <T> FetchGroupBuilder<T> of(Class<T> cls) {
111    return XServiceProvider.fetchGroupOf(cls);
112  }
113
114}