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