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