1.条件查询
(1)使用Criteria查询需要以下步骤:
①使用Session接口的createCriteria()方法创建Criteria对象
②使用Restrictions类提供的静态方法设置查询条件,这些方法返回一个Criterion对象,表示一个查询条件,Criteria接口提供了add()方法
来添加查询条件
③使用Criteria接口的list()方法执行查询
(2)下面来演示最基本的用法,没有添加任何查询条件:
- public static void main(String[] args) {
- Session session=HibernateUtil.currentSession();
- Transaction tx=session.beginTransaction();
- //创建Criteria对象
- Criteria criteria=session.createCriteria(Dept.class);
- List<Dept> list=criteria.list();
- for (Dept dept : list) {
- System.out.println(dept.getDeptName()+"\t"+dept.getDeptNo());
- }
- tx.commit();
- HibernateUtil.closeSession();
- }
- //创建Criteria对象
- Criteria criteria=session.createCriteria(Dept.class);
- //添加查询条件,一个Criterion对象就是一个查询条件,这里的location是实体类中的属性名
- Criterion criterion=Restrictions.eq("location", "NEW YORK");
- criteria.add(criterion);
- List<Dept> list=criteria.list();
- for (Dept dept : list) {
- System.out.println(dept.getDeptName()+"\t"+dept.getDeptNo());
- }
SimpleExpression Restrictions.eq(String propertyName,Object value) | 等于 |
SimpleExpression Restrictions.ne(String propertyName,Object value) | 不等于 |
SimpleExpression Restrictions.gt(String propertyName,Object value) | 大于 |
SimpleExpression Restrictions.ge(String propertyName,Object value) | 大于等于 |
SimpleExpression Restrictions.lt(String propertyName,Object value) | 小于 |
SimpleExpression Restrictions.le(String propertyName,Object value) | 小于等于 |
Criterion Restrictions.isNull(String propertyName) | 等于空值 |
Criterion Restrictions.isNotNull(String propertyName) | 非空值 |
Criterion Restrictions.in(String property,Collection values) 或 Criterion Restrictions.in(String property,Object[] values) | 等于列表 中的某一 个值
|
Criterion Restrictions.not( Restrictions.in() ) | 不等于列 表中任意一个值 |
Criterion Restrictions.between(String property,Object lo,Object hi) | 大于等于值1并 且小于等于值2 |
Criterion Restrictions.not( Restrictions.between() ) | 小于值1或者大于 值2 |
SimpleExpression Restrictions.like(String property,Object value) 或 SimpleExpression Restrictions.like(String property,Objectvalue,MatchMode matchMode) | 字符串模式匹配 |
Criterion Restrictions.ilike(String property,Object value) 或 Criterion Restrictions.ilike(String property,Objectvalue,MatchMode matchMode) | 字符串模式匹配,同 忽略大小写时 |
LogicalExpression Restrictions.and(Criterion c1,Criterion c2) | 逻辑与 |
LogicalExpression Restrictions.or(Criterion c1,Criterion c2) 或者 Disjunction Restrictions.disjunction() | 逻辑或 |
LogicalExpression Restrictions.not(Criterion expression) | 逻辑非 |
Criterion Restrictions.isEmpty(String propertyName) | 集合为空,不包含任何元素 |
Criterion Restrictions.isNotEmpty(String propertyName) | 集合不为空 |
2.排序
Hibernate提供了org.hibernate.criterion.Order类来对查询结果进行排序,在为Criteria对象添加排序条件的时候要使用addOrder()方法,而不再是add()方法
如:查询员工工资小于3000的员工并按照降序排序:
- /**
- * 1.criteria的add()方法返回的都是自身对象,所以可以通过连缀调用的方式继续添加条件;
- * 2.注意:如果实体类中的工资属性是double型的,这里的3000后要加D(或d),否则会抛出
- * 不能将Integer转换成Double类型的异常
- */
- List<Emp> list=session.createCriteria(Emp.class)
- .add(Restrictions.lt("sal", 3000D))
- .addOrder(Order.desc("sal"))
- .list();
- for (Emp emp : list) {
- System.out.println(emp.getSal());
- }
Criteria的分页同HQL的分页用法一致,都是通过setFirstResult()和setMaxResults()方法来实现的,
uniqueResult()的用法一致,我在《 Hibernate学习(二)HQL&SQL参数绑定、投影和分页以及命名查询》中已进行解释,这里就不再过多赘述。
4.连接查询
Criteria查询和HQL都支持连接查询,但是Criteria只支持内连接和迫切左外连接查询。Criteria提供了 createCriteria()和 createAlias()方法来建立内连接。
例如:查询部门名称为“ACCOUNTING”并且名字中包含“l”的员工集合
①使用createCriteria()方式
- /**
- * 1.为了防止属性的命名冲突,在使用时尽量加上别名,如“e”和“d”;
- * 2.其中的dept是Emp实体类中拥有的属性,Emp和Dept是多对一的关系
- */
- List<Emp> list=session.createCriteria(Emp.class,"e")
- .add(Restrictions.ilike("e.empName", "l",MatchMode.ANYWHERE))
- .createCriteria("dept", "d")
- .add(Restrictions.eq("d.deptName", "ACCOUNTING"))
- .list();
- for (Emp emp : list) {
- System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());
- }
- List<Emp> list=session.createCriteria(Emp.class,"e")
- .add(Restrictions.ilike("e.empName", "l",MatchMode.ANYWHERE))
- .createAlias("dept", "d")
- .add(Restrictions.eq("d.deptName", "ACCOUNTING"))
- .list();
- for (Emp emp : list) {
- System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());
- }
CLARK ACCOUNTING
MILLER ACCOUNTING
5.投影
Hibernate提供了Projection接口和Projections类来支持Criteria查询的投影。Projections类是用来构建Projection对象的工厂类,通过调用Criteria接口的setProjection()方法来设置投影属性
(1)查询单个属性时
如,查询部门的deptName属性
- /**
- * 1.setProjection()方法设置投影属性
- * 2.Property类实现了Projection接口,forName()方法制定了投影属性的名称,并返回Property对象
- */
- List<String> list=session.createCriteria(Dept.class)
- .setProjection(Property.forName("deptName"))
- .list();
- for (String string : list) {
- System.out.println(string);
- }
当投影的属性不止一个的时候,使用Projections的projectionList()方法来设置属性名称
- /**
- * projetctionList()方法得到了ProjectionList对象,ProjectionList实现了Projection接口
- */
- List<Object[]> list=session.createCriteria(Dept.class)
- .setProjection(
- Projections.projectionList()
- .add(Property.forName("deptNo"))
- .add(Property.forName("deptName"))
- )
- .list();
- for (Object[] item : list) {
- System.out.println(item[0]+"\t"+item[1]);
- }
PropertyProjection Projections.groupProperty(String propertyName) | 分组 |
PropertyProjection Projections.rowCount() | 统计记录数 |
AggregateProjection Projections.avg(String propertyName) | 统计平均值 |
AggregateProjection Projections.max(String propertyName) | 统计最大值 |
AggregateProjection Projections.min(String propertyName) | 统计最小值 |
CountProjection Projections.count(String propertyName) | 统计某一字段的非空记录数 |
AggregateProjection Projections.sum(String propertyName) | 针对某一字段求和 |
6.DetachedCriteria
Criteria接口继承了CriteriaSpecification接口,而DetachedCriteria类实现了CriteriaSpecification接口,所以两者在使用的时候类似但是两者的创建不同:
(1)Criteria是由Session对象创建
(2)DetachedCriteria创建的时候不需要Session对象
那么要DetachedCriteria又是何用呢?
在常规的web项目中,有大量的动态条件查询,程序运行时会根据用户的选择动态生成查询语句。对于分层应用来说,Web层需要传递一个查询的条件列表到业务层,业务层获得条件列表之后一次取出条件进行查询,构造查询语句。
关键是条件列表用什么构造?如果使用Map的话,Map传递的信息时非常有限的,只能传递键值对,无法传递究竟要怎样的条件运算,所以非常有限制性。
所以DetachedCriteria就可以解决这个问题,将所有的查询条件封装成DetachedCriteria对象,然后传递到业务层,业务层可以再Session范围内通过DetachedCriteria对象直接构造查询。
DetachedCriteria创建时不需要Session对象,只是在执行查询(调用list()方法)的时候需要
如:查询查询部门名称为“ACCOUNTING”并且名字中包含“l”的员工集合
- /**
- * 1.使用forClass()静态方法创建对象,同样支持条件设置和连接查询
- * 2.调用list()方法之前首先使用getExecutableCriteria()方法获取Criteria对象
- */
- DetachedCriteria dCriteria=DetachedCriteria.forClass(Emp.class,"e")
- .createAlias("e.dept", "d")
- .add(Restrictions.eq("d.deptName", "ACCOUNTING"))
- .add(Restrictions.ilike("empName", "l",MatchMode.ANYWHERE));
- List<Emp> list=dCriteria.getExecutableCriteria(session).list();
- for (Emp emp : list) {
- System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());
- }