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());
}