Criteria条件、动态、分页、排序、连接、投影、聚合、分组查询丶离线查询

1. 条件查询

1.1 建立标准查询与增加条件

  • Criteria Session.createCriteria(映射类.class)

    • 创建标准查询对象,返回Criteria对象
  • Criteria Criteria.add(Criterion对象)

    • 为标准查询添加Criterion条件,返回当前的标准查询对象
//查询一个具体部门:人事部        
criteria=session.createCriteria(Dept.class);
Criterion criterion=Restrictions.eq("dname", "人事部");
criteria.add(criterion);
Dept dept2=(Dept)criteria.uniqueResult();
System.out.println(dept2.getDname()+","+dept2.getLoc());

1.2 Restrictions比较运算

  • Criterion Restrictions.eq(String 属性,Object 值) //等于
  • Criterion Restrictions.ne(String 属性,Object 值) //不等于
  • Criterion Restrictions.gt(String 属性,Object 值) //大于
  • Criterion Restrictions.ge(String 属性,Object 值) //大于等于
  • Criterion Restrictions.lt(String 属性,Object 值) //小于
  • Criterion Restrictions.le(String 属性,Object 值) //小于等于
  • Criterion Restrictions.isNull(String 属性) //等于空值
  • Criterion Restrictions.isNotNull(String 属性) //非空值
//查询工资高于2000并且职位是CLERK的员工信息
//条件并且关系可以使用add多个Criterion
criteria=session.createCriteria(Emp.class).add(Restrictions.gt("sal", 1000d)).add(Restrictions.eq("job", "CLERK"));
List<Emp> emps=criteria.list();  

//查询不属于任何部门的员工信息   
Criterion criterion=Restrictions.isNull("dept");
criteria=session.createCriteria(Emp.class).add(criterion);
emps=criteria.list();  

1.3 Restrictions范围运算

  • Criterion Restrictions.in(String 属性,集合或数组)
    • 等于列表中的某一个值
  • Criterion Restrictions.between(String 属性,Object 值1,Object 值2)
    • 大于等于值1并且小于等于值2
//查询职位是”CLERK“或者是”SALESMAN“的员工信息,使用in做
//建立一个职位信息集合
List<String> jobs=new ArrayList<String>();
jobs.add("CLERK");
jobs.add("SALESMAN");
 
//使用Restrictions.in(属性,集合)实现数据库in功能
criteria=session.createCriteria(Emp.class).add(Restrictions.in("job", jobs));
emps=criteria.list();
//工资在2000到4000之间的员工信息
 criteria=session.createCriteria(Emp.class).add(Restrictions.between("sal", 2000d, 4000d));
 emps=criteria.list();

1.4 Restrictions模糊查询

  • Criterion Restrictions.like(String 属性,Object 值,MatchMode 模式)

    • 字符串模糊匹配,不忽略大小写
  • Criterion Restrictions.ilike(String 属性,Object 值,MatchMode 模式)

    • 字符串模糊匹配,忽略大小写
  • MatchMode静态常量

    • MatchMode.START 以指定字符串开头
    • MatchMode.END 以指定字符串结尾
    • MatchMode.ANYWHERE 包含指定字符串
    • MatchMode.EXACT 精确匹配
//查询员工名字包含"T"的员工信息
criteria=session.createCriteria(Emp.class).add(Restrictions.ilike("ename", "T",MatchMode.ANYWHERE));
emps=criteria.list();

1.5 Restrictions逻辑运算

  • Criterion Restrictions.not(Criterion对象)
    • 逻辑非!,条件成立则为false,否则为true
  • Criterion Restrictions.and(Criterion 条件1,Criterion 条件2)
    • 逻辑与&&,条件1和条件2都成立才为true,否则为false
  • Criterion Restrictions.or(Criterion 条件1,Criterion 条件2)
    • 逻辑或||,条件1或条件2只要一个成立则为true,两个都不成立则为false
  • Disjunction Restrictions.disjunction()
    • 用于存放多个或条件
//查询职位是”CLERK“或者是”SALESMAN“的员工信息
//条件或者关系使用Restrictions.or(Criterion1,Criterion2)
Criterion criterionA=Restrictions.eq("job", "CLERK");
Criterion criterionB=Restrictions.eq("job", "SALESMAN");
Criterion criterionAorB=Restrictions.or(criterionA, criterionB);
criteria=session.createCriteria(Emp.class).add(criterionAorB);
emps=criteria.list();
//查询职位是”CLERK“或者是”SALESMAN“的员工信息
 //条件或者关系使用Restrictions.or(Criterion1,Criterion2)
 criterionA=Restrictions.eq("job", "CLERK");
 criterionB=Restrictions.eq("job", "SALESMAN");
 Criterion criterionC=Restrictions.gt("sal", 1000d);
 criteria=session.createCriteria(Emp.class).add(Restrictions.disjunction().add(criterionA).add(criterionB).add(criterionC));
 emps=criteria.list();

1.6 Restrictions集合运算

  • Restrictions.isEmpty(Criterion对象)
    • 集合为空则为true,否则为false
  • Restrictions.isNotEmpty(Criterion对象)
    • 集合不为空则为true,否则为false
//查询没有员工的部门
criteria=session.createCriteria(Dept.class).add(Restrictions.isEmpty("emps"));
depts=criteria.list();

2. 动态、分页、排序查询

  • Criteria Criteria.setFirstResult(int 查询的起始位置)
    • 设置分页的查询起始位置
  • Criteria Criteria.setMaxResults(int 每页显示的行数)
    • 设置分页的每页显示的行数
  • Criteria Criteria.addOrder(Order对象)
    • 设置按指定列排序进行查询
  • Order的静态方法
    • Order Order.asc(String 属性) 升序
    • Order Order.desc(String 属性) 倒叙
Session session=HibernateUtil.currentSession();
//把条件封装成EmpCondition类
EmpCondition ec=new EmpCondition();
//给条件赋值
ec.setJob("CLERK");
ec.setSal(1000d);
ec.setStart(Date.valueOf("1985-01-01"));
Criteria criteria=session.createCriteria(Emp.class);
//根据条件是否为空而添加条件到标准查询中
if(ec.getSal()!=null){
    criteria.add(Restrictions.gt("sal", ec.getSal()));
}
if(ec.getJob()!=null){
    criteria.add(Restrictions.eq("job", ec.getJob()));
}
if(ec.getStart()!=null){
    criteria.add(Restrictions.gt("hiredate", ec.getStart()));
}
if(ec.getEnd()!=null){
    criteria.add(Restrictions.lt("hiredate", ec.getEnd()));
}
//按sal列降序排列
criteria.addOrder(Order.desc("sal"));
//设置从第几条记录开始查询
criteria.setFirstResult((2-1)*2);
//设置每页显示的记录数
criteria.setMaxResults(2);
//遍历员工集合
List<Emp> emps=criteria.list();
for(Emp emp:emps){
    System.out.println("员工:"+emp.getEname()+",职位:"+emp.getJob()+",工资:"+emp.getSal()+",入职时间:"+emp.getHiredate());
}

HibernateUtil.closeSession();

3. 连接查询

  • Criteria Criteria.createCriteria(String 属性)

    • 建立普通内链接
  • Criteria Criteria.createAlias(String 属性,String 别名)

    • 使用别名建立内连接
  • Criteria Criteria.setFetchMode(String 属性,FetchMode.JOIN)

    • 建立迫切左外连接
//查询SALES部门有没有"a"员工
Criteria criteria=session.createCriteria(Emp.class);
criteria.add(Restrictions.ilike("ename", "a",MatchMode.ANYWHERE));
criteria.createCriteria("dept").add(Restrictions.eq("dname", "SALES").ignoreCase());
List<Emp> emps=criteria.list();
//使用别名连接查询
criteria=session.createCriteria(Emp.class);
criteria.add(Restrictions.ilike("ename", "a",MatchMode.ANYWHERE));
criteria.createAlias("dept", "d").add(Restrictions.eq("d.dname", "SALES").ignoreCase());
emps=criteria.list();
//迫切左连接
criteria=session.createCriteria(Dept.class,"d");
criteria.setFetchMode("emps", FetchMode.JOIN);
criteria.add(Restrictions.eq("loc", "CHICAGO"));
List<Dept> depts=criteria.list();

4. 投影查询

  • Criteria Criteria.setProjection(Property对象)
    • 设置投影属性
  • Property Property.forName(String 属性)
    • 指定投影属性
  • ProjectionList Projections.projectionList()
    • 返回属性集合,可以存放多个属性
//投影查询单列所有部门的名称
criteria=session.createCriteria(Dept.class,"d");
criteria.setProjection(Property.forName("dname"));
List<String> dnames=criteria.list();    
//投影查询多列所有部门的名称和位置
criteria=session.createCriteria(Dept.class,"d");
criteria.setProjection(Projections.projectionList().add(Property.forName("dname")).add(Property.forName("loc")));
List<Object[]> objects=criteria.list();

5. 聚合&分组查询

  • Projections.groupProperty(String 属性)
    • 根据指定列分组
  • Projection Projections.rowCount()
    • 统计记录数
  • Projection Projections.avg(String 属性)
    • 统计平均值
  • Projection Projections.max(String 属性)
    • 统计最大值
  • Projection Projections.min(String 属性)
    • 统计最小值
  • Projection Projections.count(String 属性)
    • 统计某字段的非空记录数
  • Projection Projections.sum(String 属性)
    • 统计某一字段求和
//查询每个部门的平均工资、最高工资和最低工资
Criteria criteria=session.createCriteria(Emp.class,"e");
criteria.createAlias("e.dept", "d");
Projection projection=Projections.groupProperty("d.dname");
Projection projection1=Projections.avg("sal");
Projection projection2=Projections.max("sal");
Projection projection3=Projections.min("sal");
ProjectionList list=Projections.projectionList();
list.add(projection).add(projection1).add(projection2).add(projection3);
criteria.setProjection(list);
List<Object[]> objects=criteria.list();
for(Object[] object:objects){
    System.out.println("部门:"+object[0]+",平均工资"+object[1]+",最高工资"+object[2]+",最低工资"+object[3]);
}

6. DetachedCriteria离线查询

6.1 理解

  • DetachedCriteria和Criteria继承同一个接口、DetachedCriteria可以使用Criteria常用的方法
  • DetachedCriteria创建时不需要Session,只有真正查询时才需要Session
  • DetachedCriteria可以作为条件用于子查询

6.2 方法

  • DetachedCriteria.forClass(类名.class,[String 别名])
    • 构建指定类的查询
  • DetachedCriteria.getExecutableCriteria(session)
    • 使用Session实现真正的查询
//使用DetachedCriteria构造对Emp类的查询
DetachedCriteria detachedCriteria=DetachedCriteria.forClass(Emp.class);
//查询平均工资
detachedCriteria.setProjection(Projections.avg("sal"));
//获取session开始查询,返回平均工资
Double sal=(Double)detachedCriteria.getExecutableCriteria(session).uniqueResult();
System.out.println(sal);
 
//使用Criteria构造对Emp类的查询
criteria=session.createCriteria(Emp.class);
//使用DetachedCriteria作为Criteria的子查询的条件
criteria.add(Property.forName("sal").gt(detachedCriteria));
List<Emp> emps=criteria.list();
for(Emp emp:emps){
    System.out.println("员工:"+emp.getEname()+",工资"+emp.getSal());
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章