001package io.ebean.typequery; 002 003import io.ebean.ExpressionList; 004 005/** 006 * Base type for associated beans. 007 * 008 * @param <T> the entity bean type (normal entity bean type e.g. Customer) 009 * @param <R> the specific root query bean type (e.g. QCustomer) 010 */ 011@SuppressWarnings("rawtypes") 012public abstract class TQAssocBean<T, R> extends TQProperty<R> { 013 014 /** 015 * Construct with a property name and root instance. 016 * 017 * @param name the name of the property 018 * @param root the root query bean instance 019 */ 020 public TQAssocBean(String name, R root) { 021 this(name, root, null); 022 } 023 024 /** 025 * Construct with additional path prefix. 026 */ 027 public TQAssocBean(String name, R root, String prefix) { 028 super(name, root, prefix); 029 } 030 031 /** 032 * Eagerly fetch this association fetching all the properties. 033 */ 034 public R fetch() { 035 ((TQRootBean) _root).query().fetch(_name); 036 return _root; 037 } 038 039 /** 040 * Eagerly fetch this association using a "query join". 041 */ 042 public R fetchQuery() { 043 ((TQRootBean) _root).query().fetchQuery(_name); 044 return _root; 045 } 046 047 /** 048 * Eagerly fetch this association using L2 bean cache. 049 * Cache misses are populated via fetchQuery(). 050 */ 051 public R fetchCache() { 052 ((TQRootBean) _root).query().fetchCache(_name); 053 return _root; 054 } 055 056 /** 057 * Use lazy loading for fetching this association. 058 */ 059 public R fetchLazy() { 060 ((TQRootBean) _root).query().fetchLazy(_name); 061 return _root; 062 } 063 064 /** 065 * Eagerly fetch this association with the properties specified. 066 */ 067 public R fetch(String properties) { 068 ((TQRootBean) _root).query().fetch(_name, properties); 069 return _root; 070 } 071 072 /** 073 * Eagerly fetch this association using a "query join" with the properties specified. 074 */ 075 public R fetchQuery(String properties) { 076 ((TQRootBean) _root).query().fetchQuery(_name, properties); 077 return _root; 078 } 079 080 /** 081 * Eagerly fetch this association using L2 cache with the properties specified. 082 * Cache misses are populated via fetchQuery(). 083 */ 084 public R fetchCache(String properties) { 085 ((TQRootBean) _root).query().fetchCache(_name, properties); 086 return _root; 087 } 088 089 /** 090 * Deprecated in favor of fetch(). 091 * 092 * @deprecated 093 */ 094 public R fetchAll() { 095 return fetch(); 096 } 097 098 /** 099 * Eagerly fetch this association fetching some of the properties. 100 */ 101 @SafeVarargs 102 protected final R fetchProperties(TQProperty<?>... props) { 103 ((TQRootBean) _root).query().fetch(_name, properties(props)); 104 return _root; 105 } 106 107 /** 108 * Eagerly fetch query this association fetching some of the properties. 109 */ 110 @SafeVarargs 111 protected final R fetchQueryProperties(TQProperty<?>... props) { 112 ((TQRootBean) _root).query().fetchQuery(_name, properties(props)); 113 return _root; 114 } 115 116 /** 117 * Eagerly fetch this association using L2 bean cache. 118 */ 119 @SafeVarargs 120 protected final R fetchCacheProperties(TQProperty<?>... props) { 121 ((TQRootBean) _root).query().fetchCache(_name, properties(props)); 122 return _root; 123 } 124 125 /** 126 * Eagerly fetch query this association fetching some of the properties. 127 */ 128 @SafeVarargs 129 protected final R fetchLazyProperties(TQProperty<?>... props) { 130 ((TQRootBean) _root).query().fetchLazy(_name, properties(props)); 131 return _root; 132 } 133 134 /** 135 * Append the properties as a comma delimited string. 136 */ 137 @SafeVarargs 138 protected final String properties(TQProperty<?>... props) { 139 StringBuilder selectProps = new StringBuilder(50); 140 for (int i = 0; i < props.length; i++) { 141 if (i > 0) { 142 selectProps.append(","); 143 } 144 selectProps.append(props[i].propertyName()); 145 } 146 return selectProps.toString(); 147 } 148 149 /** 150 * Is equal to by ID property. 151 */ 152 public R eq(T other) { 153 expr().eq(_name, other); 154 return _root; 155 } 156 157 /** 158 * Is equal to by ID property. 159 */ 160 public R equalTo(T other) { 161 return eq(other); 162 } 163 164 /** 165 * Is not equal to by ID property. 166 */ 167 public R ne(T other) { 168 expr().ne(_name, other); 169 return _root; 170 } 171 172 /** 173 * Is not equal to by ID property. 174 */ 175 public R notEqualTo(T other) { 176 return ne(other); 177 } 178 179 /** 180 * Apply a filter when fetching these beans. 181 */ 182 public R filterMany(ExpressionList<T> filter) { 183 184 @SuppressWarnings("unchecked") 185 ExpressionList<T> expressionList = (ExpressionList<T>) expr().filterMany(_name); 186 expressionList.addAll(filter); 187 return _root; 188 } 189 190 /** 191 * Apply a filter when fetching these beans. 192 * <p> 193 * The expressions can use any valid Ebean expression and contain 194 * placeholders for bind values using <code>?</code> or <code>?1</code> style. 195 * </p> 196 * 197 * <pre>{@code 198 * 199 * new QCustomer() 200 * .name.startsWith("Postgres") 201 * .contacts.filterMany("firstName istartsWith ?", "Rob") 202 * .findList(); 203 * 204 * }</pre> 205 * 206 * <pre>{@code 207 * 208 * new QCustomer() 209 * .name.startsWith("Postgres") 210 * .contacts.filterMany("whenCreated inRange ? to ?", startDate, endDate) 211 * .findList(); 212 * 213 * }</pre> 214 * 215 * @param expressions The expressions including and, or, not etc with ? and ?1 bind params. 216 * @param params The bind parameter values 217 */ 218 public R filterMany(String expressions, Object... params) { 219 expr().filterMany(_name, expressions, params); 220 return _root; 221 } 222 223 /** 224 * Is empty for a collection property. 225 * <p> 226 * This effectively adds a not exists sub-query on the collection property. 227 * </p> 228 * <p> 229 * This expression only works on OneToMany and ManyToMany properties. 230 * </p> 231 */ 232 public R isEmpty() { 233 expr().isEmpty(_name); 234 return _root; 235 } 236 237 /** 238 * Is not empty for a collection property. 239 * <p> 240 * This effectively adds an exists sub-query on the collection property. 241 * </p> 242 * <p> 243 * This expression only works on OneToMany and ManyToMany properties. 244 * </p> 245 */ 246 public R isNotEmpty() { 247 expr().isNotEmpty(_name); 248 return _root; 249 } 250 251}