2009.12.31――hibernate DetachedCriteria Criterion和Example
2011年09月14日
2009.12.31――hibernate DetachedCriteria Criterion和Example
参考:http://javaeyetianjin.group.iteye.com/group/topic/ 10621
http://blog.csdn.net/hi_jess/archive/2009/10/08/46 41237.aspx
QBE:query by Example QBC:query by Criteria Criteria:代表一次查询 Creterion:代表一个查询条件 Restrictions:产生查询条件的工具类 Example继承Criterion DetachedCriteria继承CriteriaSpecification Criteria也继承CriteriaSpecification
1.DetachedCriteria
在常规的Web编程中,有大量的动态条件查询,即用户在网页上面自由选择某些条件,程序根据用户的选择条件,动态生成SQL语句,进行查询。
DetachedCriteria可以解决这个问题,即在web层,程序员使用DetachedCriteria来构造查询条件,然后将这个DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后,可以在session范围内直接构造Criteria,进行查询。就此,查询语句的构造完全被搬离到web层实现,而业务层则只负责完成持久化和查询的封装即可,与查询条件构造完全解耦,非常完美!这恐怕也是以前很多企图在web层代码中构造HQL语句的人想实现的梦想吧!
示例代码片段如下:
web层程序构造查询条件:
Java代码
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); detachedCriteria.add(Restrictions.eq("name", "department")).createAlias("employees", "e").add(Restrictions.gt(("e.age"), new Integer(20)));
Department和Employee是一对多关联,查询条件为:
名称是“department”开发部门;
部门里面的雇员年龄大于20岁;
业务层对象使用该条件执行查询:
Java代码
detachedCriteria.getExecutableCriteria(session);.l ist();;
最大的意义在于,业务层代码是固定不变的,所有查询条件的构造都在web层完成,业务层只负责在session内执行之。这样代码就可放之四海而皆准,都无须修改了
比较一个属性可以这样:
detachedCriteria.add(Restrictions.eq(XXX.PROP_ID,I nteger.parseInt(id)));
如果比较的属性本身类型是对象,那么可以这样
detachedCriteria.add(Restrictions.eq(XXX.PROP_BM+" .id",Integer.parseInt(bmid)));
以上面的语句为例,如果我比较其他属性
detachedCriteria.add(Restrictions.eq(XXX.PROP_BM+" .bmmc",bmmc));
这样是不行的
解决方法:先定义一个别名
detachedCriteria.createAlias(XXX.PROP_BM, "bm");然后可以这样使用了
detachedCriteria.add("bm.bmmc",bmmc));
个人总结:不使用别名,本身是对象的属性后面只能跟其主键属性,比较其他属性要用别名
2.Criteria
Criteria对SQL进行封装,让开发人员可以用对象的方式来对数据库进行操作,例如下面的查询User表格中的
所有数据:
Criteria criteria = session.createCriteria(User.class); // 查询user所有字段 List users = criteria.list(); Iterator iterator = users.iterator(); System.out.println("id \t name/age"); while(iterator.hasNext()) { User user = (User) iterator.next(); System.out.println(user.getId() + " \t " + user.getName() + "/" + user.getAge()); }
Hibernate实际上使用以下的SQL来查询数据库:
select this_.id as id0_, this_.name as name0_0_, this_.age as age0_0_ from user this_
Criteria实际上只是个容器,如果想要设定查询条件,则要使用add()方法加入Restrictions的条件限制,例
如查询age大于20且小于40的数据:
Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.gt("age", new Integer(20))); criteria.add(Restrictions.lt("age", new Integer(40))); List users = criteria.list();
您也可以使用逻辑组合来进行查询,例如结合age等于(eq)20或(or)age为空(isNull)的条件:
Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.or( Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age") )); List users = criteria.list();
也可以使用sqlRestriction()方法来提供SQL语法作限定查询,例如查询name以cater开头的数据:
Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.sqlRestriction("{alias}. name LIKE (?)", "cater%", Hibernate.STRING)); List users = criteria.list();
其中alias将被替换为与User类别相关的名称,而?将被替换为cater%,也就是第二个参数所提供的值,在SQL
撰写时,不必再写WHERE,如果有多个查询条件,例如BETWEEN子句的查询,则可以如下:
Criteria criteria = session.createCriteria(User.class); Integer[] ages = {new Integer(20), new Integer(40)}; Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER}; criteria.add(Restrictions.sqlRestriction("{alias}. age BETWEEN (?) AND (?)", ages, types)); List users = criteria.list();
3.Restrictions
Restrictions的几个常用限定查询方法如下表所示:
方法 说明 Restrictions.eq 等于 Restrictions.allEq 使用Map,使用key/value进行多个等于的比对 Restrictions.gt 大于 > Restrictions.ge 大于等于 >= Restrictions.lt 小于
2011年09月14日
2009.12.31――hibernate DetachedCriteria Criterion和Example
参考:http://javaeyetianjin.group.iteye.com/group/topic/ 10621
http://blog.csdn.net/hi_jess/archive/2009/10/08/46 41237.aspx
QBE:query by Example QBC:query by Criteria Criteria:代表一次查询 Creterion:代表一个查询条件 Restrictions:产生查询条件的工具类 Example继承Criterion DetachedCriteria继承CriteriaSpecification Criteria也继承CriteriaSpecification
1.DetachedCriteria
在常规的Web编程中,有大量的动态条件查询,即用户在网页上面自由选择某些条件,程序根据用户的选择条件,动态生成SQL语句,进行查询。
DetachedCriteria可以解决这个问题,即在web层,程序员使用DetachedCriteria来构造查询条件,然后将这个DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后,可以在session范围内直接构造Criteria,进行查询。就此,查询语句的构造完全被搬离到web层实现,而业务层则只负责完成持久化和查询的封装即可,与查询条件构造完全解耦,非常完美!这恐怕也是以前很多企图在web层代码中构造HQL语句的人想实现的梦想吧!
示例代码片段如下:
web层程序构造查询条件:
Java代码
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); detachedCriteria.add(Restrictions.eq("name", "department")).createAlias("employees", "e").add(Restrictions.gt(("e.age"), new Integer(20)));
Department和Employee是一对多关联,查询条件为:
名称是“department”开发部门;
部门里面的雇员年龄大于20岁;
业务层对象使用该条件执行查询:
Java代码
detachedCriteria.getExecutableCriteria(session);.l ist();;
最大的意义在于,业务层代码是固定不变的,所有查询条件的构造都在web层完成,业务层只负责在session内执行之。这样代码就可放之四海而皆准,都无须修改了
比较一个属性可以这样:
detachedCriteria.add(Restrictions.eq(XXX.PROP_ID,I nteger.parseInt(id)));
如果比较的属性本身类型是对象,那么可以这样
detachedCriteria.add(Restrictions.eq(XXX.PROP_BM+" .id",Integer.parseInt(bmid)));
以上面的语句为例,如果我比较其他属性
detachedCriteria.add(Restrictions.eq(XXX.PROP_BM+" .bmmc",bmmc));
这样是不行的
解决方法:先定义一个别名
detachedCriteria.createAlias(XXX.PROP_BM, "bm");然后可以这样使用了
detachedCriteria.add("bm.bmmc",bmmc));
个人总结:不使用别名,本身是对象的属性后面只能跟其主键属性,比较其他属性要用别名
2.Criteria
Criteria对SQL进行封装,让开发人员可以用对象的方式来对数据库进行操作,例如下面的查询User表格中的
所有数据:
Criteria criteria = session.createCriteria(User.class); // 查询user所有字段 List users = criteria.list(); Iterator iterator = users.iterator(); System.out.println("id \t name/age"); while(iterator.hasNext()) { User user = (User) iterator.next(); System.out.println(user.getId() + " \t " + user.getName() + "/" + user.getAge()); }
Hibernate实际上使用以下的SQL来查询数据库:
select this_.id as id0_, this_.name as name0_0_, this_.age as age0_0_ from user this_
Criteria实际上只是个容器,如果想要设定查询条件,则要使用add()方法加入Restrictions的条件限制,例
如查询age大于20且小于40的数据:
Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.gt("age", new Integer(20))); criteria.add(Restrictions.lt("age", new Integer(40))); List users = criteria.list();
您也可以使用逻辑组合来进行查询,例如结合age等于(eq)20或(or)age为空(isNull)的条件:
Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.or( Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age") )); List users = criteria.list();
也可以使用sqlRestriction()方法来提供SQL语法作限定查询,例如查询name以cater开头的数据:
Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.sqlRestriction("{alias}. name LIKE (?)", "cater%", Hibernate.STRING)); List users = criteria.list();
其中alias将被替换为与User类别相关的名称,而?将被替换为cater%,也就是第二个参数所提供的值,在SQL
撰写时,不必再写WHERE,如果有多个查询条件,例如BETWEEN子句的查询,则可以如下:
Criteria criteria = session.createCriteria(User.class); Integer[] ages = {new Integer(20), new Integer(40)}; Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER}; criteria.add(Restrictions.sqlRestriction("{alias}. age BETWEEN (?) AND (?)", ages, types)); List users = criteria.list();
3.Restrictions
Restrictions的几个常用限定查询方法如下表所示:
方法 说明 Restrictions.eq 等于 Restrictions.allEq 使用Map,使用key/value进行多个等于的比对 Restrictions.gt 大于 > Restrictions.ge 大于等于 >= Restrictions.lt 小于