自定义查询PropertyFilter与QBC
1、页面参数传递规则
参数规则:前缀+"_"+操作符+属性类型+"_"+属性名称
前缀:以"filter"开头
操作符:NE,EQ, LIKE,SLIKE,ELIKE, LT, GT, LE, GE;//不等于,等于,全模糊匹配,左匹配、右匹配,小于、大于
属性类型:S代表String,I代表Integer,L代表Long, N代表Double, D代表Date,B代表Boolean
属性名称:bo属性名称
Filter_ EQD_taskDate
1)常用查询
filter_LIKES_name 等价于 "from Menu mwhere m.name like '%?%'"
1)多个属性间用"_OR_"分割
filter_EQL_id_OR_parentId 等价于 "from Menu mwhere m.id = ? or m.parentId =?"
2)BO包含实体的子属性以两条下划线分割"__"(注:非主键需要设置别名参看第5点【使用别名的查询】)
filter_EQL_id_OR_parentMenu__id等价于 " from Menu m where m.id =? or m.parentMenu.id =?"
public class Menu{
private String id;//主键ID
private Menu parentMenu;//父级菜单
}
2、自定义构造PropertyFilter,无需前缀,其余不变。
例如:
//根据过来规则构造页面传递的参数
List<PropertyFilter>filters = HibernateWebUtils
.buildPropertyFilters(Struts2Utils.getRequest());
PropertyFilter propertyFilter = newPropertyFilter("LIKES_name","菜单管理");
//自定义的过滤规则添加到filters中进行分页查询
filters.add(propertyFilter);
//等价于 "from Menu mwhere m.name like '%菜单管理%'"
3、PropertyFilter结合Hibernate QBC查询.
注意:PropertyFilter仅支持NE,EQ, LIKE,SLIKE,ELIKE, LT, GT, LE, GE这几种查询方式
如果需求超出以上范围需要按照原始方式查询数据或者直接使用Hibernate QBC查询方式
类EntityManager提供了PropertyFilter转换成Criterion的方法,
这样可以结合PropertyFilter以及原始QBC查询满足不同需求
List<PropertyFilter>转Criterion[]
public Criterion[] getCriterionsByFilter(List<PropertyFilter>filters)
自定义Criterion查询:通过以下方法实现分页查询
publicPage<T> findByCriteria(Page<T> page, Criterion... criterions)
throws DaoException, SystemException,ServiceException
示例代码:
//根据过来规则构造页面传递的参数
List<PropertyFilter> filters =HibernateWebUtils
.buildPropertyFilters(Struts2Utils.getRequest());
//PropertyFilter转换Criterion
Criterion[] cs = sensorDataReportService.getCriterionsByFilter(filters);
//between条件
Criterion c = Restrictions.between("createTime",new Date(), new Date());\
//合并查询条件
cs = (Criterion[])ArrayUtils.add(cs, 0, c);
//分页查询
Page<Menu>p = new Page<Menu>(20);//分页对象
p =menuManger.findByCriteria(p, cs);
public void eqJoin(String key,Object val) {
if (val != null && val != "") {
String[] keys = key.split("\\.");
switch (keys.length) {
case 3:
detachedCriteria.createCriteria(keys[0]).createCriteria(keys[1]).add(Restrictions.eq(keys[2], val));
break;
case 4:
detachedCriteria.createCriteria(keys[0]).createCriteria(keys[1]).
createCriteria(keys[2]).add(Restrictions.eq(keys[3], val));
break;
case 5:
detachedCriteria.createCriteria(keys[0]).
createCriteria(keys[1]).createCriteria(keys[2]).
createCriteria(keys[3]).add(Restrictions.eq(keys[4], val));
break;
}
flag = true;
}
}
4、附QBC参数构造方法
Restrictions工具类:
eq --> equal,=等于.
ne --> not equal,<>不等于.
allEq --> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions .eq 的效果
gt --> great-than > 大于
ge --> great-equal >= 大于等于
lt --> less-than, < 小于
le --> less-equal <= 小于等于
between --> 对应SQL的between子句
like --> 对应SQL的LIKE子句
in --> 对应SQL的in子句
and --> and 关系
or --> or 关系
isNull --> 判断属性是否为空,为空则返回true
isNotNull --> 与isNull相反
sqlRestriction --> SQL限定的查询
Order.asc --> 根据传入的字段进行升序排序
Order.desc --> 根据传入的字段进行降序排序
MatchMode.EXACT --> 字符串精确匹配.相当于"like 'value'"
MatchMode.ANYWHERE --> 字符串在中间匹配.相当于"like '%value%'"
MatchMode.START --> 字符串在最前面的位置.相当于"like 'value%'"
MatchMode.END --> 字符串在最后面的位置.相当于"like '%value'"
5、使用别名的查询
在使用外键查询的时候会报错,可能是由于Hibernate自身的限制,具体原因未考察,只知道这个时候需要使用别名查询。
例如:
//能够正常使用
PropertyFilterp = Propertyfilter("EQL_parentMenu__id","1");
//等价于 “from Menu m wherem.parentMenu.id = ?”
// 无效方式
PropertyFilterp = Propertyfilter("LIKES_parentMenu__name","管理");
//等价于 “from Menu m where m.parentMenu.namelike ?”(此HQL语句是可以正常查询出数据)
自定义查询只是简单的一种封装,如果要使用别名查询的,可以自行扩展DAO实现相关查询需求。
扩展DAO层,设置别名(其实只要覆盖父类方法即可)
@Repository
public classMenuDao extends HibernateDao<Menu, Long> {
/**
* 设置别名(覆盖父类SimpleHibernateDao方法).
* @param filters
* @return
*/
public CriteriacreateCriteria(final Criterion... criterions) {
Criteria criteria =getSession().createCriteria(entityClass);
//设置别名
criteria.createAlias("parentMenu", "pm");
for (Criterion c : criterions) {
criteria.add(c);
}
return criteria;
}
}
使用方法(特别注意:使用“LIKES_pm__name”而非“LIKES_parentMenu__name”)
List<PropertyFilter>filters = HibernateWebUtils.buildPropertyFilters(Struts2Utils.getRequest());
PropertyFilterp = Propertyfilter("LIKES_pm__name","管理");
filters.add(p);