Added comments for the search builder classes on how to use them

This commit is contained in:
Alex Huang 2013-09-28 11:50:02 -07:00
parent b60eef3e82
commit b998fba4da
2 changed files with 149 additions and 13 deletions

View File

@ -23,6 +23,39 @@ import java.util.UUID;
import com.cloud.utils.db.SearchCriteria.Op;
/**
* GenericQueryBuilder builds a search query during runtime. It allows the
* search query to be built completely in Java rather than part SQL fragments
* and part entity field like HQL or JPQL. This class is different from
* GenericSearchBuilder in that it is used for building queries during runtime
* where GenericSearchBuilder expects the query to be built during load time
* and parameterized values to be set during runtime.
*
* GenericQueryBuilder allows results to be a native type, the entity bean,
* and a composite type. If you are just retrieving the entity bean, there
* is a simpler class called QueryBuilder that you can use. The usage
* is approximately the same.
*
* <code>
* // Note that in the following search, it selects a func COUNT to be the
* // return result so for the second parameterized type is long.
* // Note the entity object itself must have came from search and
* // it uses the getters of the object to retrieve the field used in the search.
*
* GenericQueryBuilder<HostVO, Long> sc = GenericQueryBuilder.create(HostVO.class, Long.class);
* HostVO entity = CountSearch.entity();
* sc.select(null, FUNC.COUNT, null, null).where(entity.getType(), Op.EQ, Host.Type.Routing);
* sc.and(entity.getCreated(), Op.LT, new Date());
* Long count = sc.find();
*
* </code> *
*
* @see GenericSearchBuilder
* @see QueryBuilder
*
* @param <T> Entity object to perform the search on
* @param <K> Result object
*/
public class GenericQueryBuilder<T, K> extends SearchBase<GenericQueryBuilder<T, K>, T, K> {
final HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
@ -30,6 +63,12 @@ public class GenericQueryBuilder<T, K> extends SearchBase<GenericQueryBuilder<T,
super(entityType, resultType);
}
/**
* Creator method for GenericQueryBuilder.
* @param entityType Entity to search on
* @param resultType Result to return
* @return GenericQueryBuilder
*/
@SuppressWarnings("unchecked")
static public <T, K> GenericQueryBuilder<T, K> create(Class<T> entityType, Class<K> resultType) {
GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
@ -37,31 +76,60 @@ public class GenericQueryBuilder<T, K> extends SearchBase<GenericQueryBuilder<T,
return new GenericQueryBuilder<T, K>(entityType, resultType);
}
public GenericQueryBuilder<T, K> and(Object useless, Op op, Object... values) {
/**
* Adds AND search condition
*
* @param field the field of the entity to perform the search on.
* @param op operator
* @param values parameterized values
* @return this
*/
public GenericQueryBuilder<T, K> and(Object field, Op op, Object... values) {
String uuid = UUID.randomUUID().toString();
constructCondition(uuid, " AND ", _specifiedAttrs.get(0), op);
_params.put(uuid, values);
return this;
}
public GenericQueryBuilder<T, K> or(Object useless, Op op, Object... values) {
/**
* Adds OR search condition
*
* @param field the field of the entity to perform the search on.
* @param op operator
* @param values parameterized values
* @return this
*/
public GenericQueryBuilder<T, K> or(Object field, Op op, Object... values) {
String uuid = UUID.randomUUID().toString();
constructCondition(uuid, " OR ", _specifiedAttrs.get(0), op);
_params.put(uuid, values);
return this;
}
protected GenericQueryBuilder<T, K> left(Object useless, Op op, Object... values) {
protected GenericQueryBuilder<T, K> left(Object field, Op op, Object... values) {
String uuid = UUID.randomUUID().toString();
constructCondition(uuid, " ( ", _specifiedAttrs.get(0), op);
_params.put(uuid, values);
return this;
}
public GenericQueryBuilder<T, K> op(Object useless, Op op, Object... values) {
return left(useless, op, values);
/**
* Adds search condition that starts with an open parenthesis. Call cp()
* to close the parenthesis.
*
* @param field the field of the entity to perform the search on.
* @param op operator
* @param values parameterized values
* @return this
*/
public GenericQueryBuilder<T, K> op(Object field, Op op, Object... values) {
return left(field, op, values);
}
/**
* If the query is supposed to return a list, use this.
* @return List of result objects
*/
@SuppressWarnings("unchecked")
public List<K> list() {
finalize();
@ -75,6 +143,9 @@ public class GenericQueryBuilder<T, K> extends SearchBase<GenericQueryBuilder<T,
}
}
/**
* Creates a SearchCriteria to be used with dao objects.
*/
@Override
public SearchCriteria<K> create() {
SearchCriteria<K> sc = super.create();
@ -86,11 +157,20 @@ public class GenericQueryBuilder<T, K> extends SearchBase<GenericQueryBuilder<T,
return _selects == null || _selects.size() == 0;
}
/**
* Convenience method to find the result so the result won't be a list.
* @return result as specified.
*/
@SuppressWarnings("unchecked")
public K find() {
finalize();
@SuppressWarnings("rawtypes")
SearchCriteria sc1 = create();
return (K)_dao.findOneBy(sc1);
if (isSelectAll()) {
@SuppressWarnings("rawtypes")
SearchCriteria sc1 = create();
return (K)_dao.findOneBy(sc1);
} else {
List<K> lst = list();
return lst.get(0);
}
}
}

View File

@ -36,6 +36,28 @@ import com.cloud.utils.db.SearchCriteria.Op;
* runtime and, more importantly, the proper construction can be checked when
* components are being loaded. However, if you prefer to just construct
* the entire search at runtime, you can use GenericQueryBuilder.
*
* <code>
* // To specify the GenericSearchBuilder, you should do this at load time.
* // Note that in the following search, it selects a func COUNT to be the
* // return result so for the second parameterized type is long. It also
* // presets the type in the search and declares created to be set during
* // runtime. Note the entity object itself must have came from search and
* // it uses the getters of the object to retrieve the field used in the search.
*
* GenericSearchBuilder<HostVO, Long> CountSearch = _hostDao.createSearchBuilder(Long.class);
* HostVO entity = CountSearch.entity();
* CountSearch.select(null, FUNC.COUNT, null, null).where(entity.getType(), Op.EQ).value(Host.Type.Routing);
* CountSearch.and(entity.getCreated(), Op.LT, "create_date").done();
*
* // Later in the code during runtime
* SearchCriteria<Long> sc = CountSearch.create();
* sc.setParameter("create_date", new Date());
* Long count = _hostDao.customizedSearch(sc, null);
* </code>
*
* @see GenericQueryBuilder for runtime construction of search query
* @see SearchBuilder for returning VO objects itself
*
* @param <T> VO object this Search is build for.
* @param <K> Result object that should contain the results.
@ -118,11 +140,13 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
}
/**
* open parenthesis
* @param field
* @param op
* @param name
* @return
* Adds an condition that starts with open parenthesis. Use cp() to close
* the parenthesis.
*
* @param field field of the entity object
* @param op operator
* @param name parameter name used to set the value later
* @return this
*/
public GenericSearchBuilder<T, K> op(Object field, Op op, String name) {
return left(field, op, name);
@ -132,6 +156,15 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return left(field, op);
}
/**
* Adds an condition that starts with open parenthesis. Use cp() to close
* the parenthesis.
*
* @param name parameter name used to set the parameter value later.
* @param field field of the entity object
* @param op operator
* @return this
*/
public GenericSearchBuilder<T, K> op(String name, Object field, Op op) {
return left(field, op, name);
}
@ -149,16 +182,39 @@ public class GenericSearchBuilder<T, K> extends SearchBase<GenericSearchBuilder<
return this;
}
/**
* Adds an OR condition
*
* @param field field of the entity object
* @param op operator
* @param name parameter name
* @return this
*/
public GenericSearchBuilder<T, K> or(Object field, Op op, String name) {
constructCondition(name, " OR ", _specifiedAttrs.get(0), op);
return this;
}
/**
* Adds an OR condition but the values can be preset
*
* @param field field of the entity object
* @param op operator
* @return Preset
*/
public Preset or(Object field, Op op) {
Condition condition = constructCondition(UUID.randomUUID().toString(), " OR ", _specifiedAttrs.get(0), op);
return new Preset(this, condition);
}
/**
* Convenience method to create the search criteria and set a
* parameter in the search.
*
* @param name parameter name set during construction
* @param values values to be inserted for that parameter
* @return SearchCriteria
*/
public SearchCriteria<K> create(String name, Object... values) {
SearchCriteria<K> sc = create();
sc.setParameters(name, values);