Criteria、Criterion接口和Expression类组成,他支持在运行时动态生成查询语句。
Criteria查询是Hibernate提供的一种查询方式
Hibernate检索方式: PO=JavaBean+xml OID
Hibernate提供了5种检索对象的方式
1.导航对象图检索方式:根据已经加载的对象导航到其他对象
from Emp e group by e.dept.deptName
2.OID检索方式:按照对象的OID来检索对象 get/load
3.HQL检索方式:使用面向对象的HQL查询语言
4.QBC检索方式:使用QBC(Query By Criteria)API来检索对象,这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口
5.本地SQL检索方式:使用本地数据库的SQL查询语句
createSqlQuery();
本文案例提供类:Emp、Dept
当前案例中所有Criteria查询条件类型皆为Criterion类型 即Restrictions为我们提供的这些静态方法返回值类型皆返回Criterion类型
Restrictions
1.简单的查询 条件查询员工信息
1 public void Test1(){ 2 Criteria criteria = session.createCriteria(Emp.class); 3 criteria.createAlias("dept","d"); 4 Criterion criterion= Restrictions.eq("d.deptName", "SALES"); 5 criteria.add(criterion); 6 List<Emp> list = criteria.list(); 7 for (Emp emp : list) { 8 System.out.println(emp.getEmpName()); 9 } 10 }
解析: 其中使用Restrictions的eq方法 找出数据库中deptName列中名字叫做sales的员工
2.字符串模糊匹配
1 public void Test2(){ 2 Criteria criteria=session.createCriteria(Emp.class); 3 //like 字符串模式匹配 iLike:字符串模式匹配,同时忽略大小写 4 Criterion criterion = Restrictions.like("empName", "S",MatchMode.EXACT); //其中exact是指精确匹配 5 criteria.add(criterion); 6 List<Emp> list = criteria.list(); 7 for (Emp emp : list) { 8 System.out.println(emp.getEmpName()); 9 } 10 tx.commit(); 11 }
解析:Restrictions类提供了几个静态类让我们使用 此处就是使用了like()方法来查询出员工名字是S的人。
第三个参数是MatchMode提供的静态常亮用于指定字符串模式匹配 取值分别有:
1 start 员工姓名以S 开头 2 end 员工姓名以S 结尾 3 anywhere 员工姓名中包含S即可 4 exact 员工姓名是S(用于精确匹配)
3.范围运算符
public void test4(){ Criteria criteria=session.createCriteria(Emp.class); //将bj和sh放入List<String> List<String> job=new ArrayList<String>(); job.add("MANAGER"); //citys.add("sh"); Criterion criterion = Restrictions.in("job",job); criteria.add(criterion); List<Emp> list = criteria.list(); for (Emp emp: list) { System.out.println(emp.getEmpName()); } tx.commit(); }
解析:将查询条件放入List<String> 泛型中 使用Restrictions的in方法来查询符合条件的员工信息
4.连接查询
1 public void test5(){ 2 Session session = HibernateUtil.getSession(); 3 Transaction tx=session.beginTransaction(); 4 Criteria criteria = session.createCriteria(Emp.class); 5 criteria.createAlias("dept", "d"); 6 Criterion criterion = Restrictions.eq("d.deptName", "财务部"); 7 criteria.add(criterion); 8 List<Emp> list = criteria.list(); 9 for (Emp dept : list) { 10 System.out.println(dept.getEmpName()); 11 } 12 tx.commit(); 13 }
解析:给Emp类中dept属性通过createAlias(“关联属性的路径 一般是类型的某个外键属性”,“别名”)方法设置别名为"d" 然后通过dept中的deptName属性来查找相应数据。
5.逻辑运算(给criteria添加多个匹配条件)
1 public void Test3(){ 2 Criteria criteria=session.createCriteria(Emp.class); 3 Criterion criterion1 = Restrictions.eq("job", "MANAGER"); 4 Criterion criterion2 = Restrictions.ilike("empName", "C",MatchMode.ANYWHERE); 5 Criterion and = Restrictions.disjunction().add(criterion2).add(criterion1);//(criterion1,criterion2) 6 criteria.add(and); 7 List<Emp> list = criteria.list(); 8 for (Emp emp : list) { 9 System.out.println(emp.getEmpName()); 10 } 11 tx.commit(); 12 }
解析: Restrictions.and() 该方法返回的依然是条件 需要再次的通过criteria.add(and) 方法将其添加到其中。Disjunction()方法加入多个条件的逻辑或操作。
6.排序
1 public void test9(){ 2 Session session = HibernateUtil.getSession(); 3 Transaction tx=session.beginTransaction(); 4 Criteria criteria=session.createCriteria(Emp.class); 5 Criterion criterion= Restrictions.gt("empId",0); 6 7 criteria.add(criterion).addOrder(Order.asc("empId")); 8 List<Emp> list = criteria.list(); 9 for (Emp emp : list) { 10 System.out.println(emp.getEmpName()); 11 } 12 tx.commit(); 13 }
解析:当前案例同过add()方法添加了查询条件后,再通过addOrder()方法通过指定的列进行正向排序。
7.集合运算
1 public void collectionTest(){ 2 Criteria criteria = session.createCriteria(Dept.class); 3 4 Criterion criterion = Restrictions.isEmpty("emps"); 5 6 criteria.add(criterion); 8 9 List<Dept> list = criteria.list(); 10 for (Dept dept : list) { 11 System.out.println(dept.getDeptName()); 12 } 13 }
解析:通过判断当前部门下的员工集合是否为空来进行集合运算 上面的操作:是查找出所有员工集合为空的部门名称
8.动态查询
1 public void dynamicTest(){ 2 Criteria criteria = session.createCriteria(Emp.class); 3 //00.构建出一个和page对应的条件类,依次判定条件是否为空 4 EmpCondition condition=new EmpCondition(); 5 condition.setEmpCity("bj"); 6 condition.setEmpId(0); 7 8 //1.2判定之后,动态拼接检索条件 9 if (condition.getEmpCity()!=null) { 10 //用户填写了地址作为检索条件 11 criteria.add(Restrictions.eq("empCity", condition.getEmpCity())); 12 } 13 if(condition.getEmpId()!=null){ 14 //用户填写用户编号作为筛选条件 15 criteria.add(Restrictions.gt("empId", condition.getEmpId())); 16 } 17 List<Emp> list = criteria.list(); 18 for (Emp emp : list) { 19 System.out.println(emp.getEmpName()); 20 } 21 }
解析:通过扩展类将查询的具体属性封装起来,可以添加多个匹配条件来查询数据
9.分页
1 public void test10(){ 2 Session session = HibernateUtil.getSession(); 3 Transaction tx=session.beginTransaction(); 4 Criteria criteria=session.createCriteria(Emp.class); 5 Projection projection = Projections.count("empId"); 6 criteria.setProjection(projection); 7 //求出总记录数 8 Integer count = ((Long)criteria.uniqueResult()).intValue(); 9 int pageSize=3; 10 int pageIndex=2; 11 Criteria criteria2=session.createCriteria(Emp.class); 12 //数据的拎取 13 criteria2.setFirstResult((pageIndex-1)*pageSize); 14 criteria2.setMaxResults(pageSize); 15 List<Emp> list = criteria2.list(); 16 for (Emp emp : list) { 17 System.out.println(emp.getEmpName()); 18 } 19 tx.commit(); 20 }
解析:
Criteria接口提供了设置分页的方法
setFirstResult(int firstResult) 起始记录的索引
setMaxResult(int maxResult) 最大记录条数
10.DetachedCriteria 查询
DetachedCriteria 创建时不需要Session对象。适用于有大量动态条件查询,即用户在网页上自由选择某些条件,程序根据用户的选择条件,动态生成SQL语句,进行查询。
针对这种需求,对于分层应用程序来说,文本层需要传递一个查询的条件列表给业务层对象,业务层对象获得这个条件列表 之后,依次取出条件,构造查询语句。
查询结果也可作为查询条件:例如当查询结果为平均成绩时,就可以其他成绩来和平均成绩做对比。
1 /** 2 * 1.11 DetachedCriteria和Criteria功能类似,它实现了CriteriaSpecification接口 3 Criteria是由Session对象创建的 4 DetachedCriteria创建时不需要Session对象 5 使用DetachedCriteria来构造查询条件 6 可以把DetachedCriteria作为方法参数传递给业务层 7 * 查询开发部的员工 8 * */ 9 @Test 10 public void detachedCriteriaTest(){ 11 //难度 3颗星 重要程度五颗星 ★★★★★ 12 //1.构建一个Detached对象 13 DetachedCriteria detachedCriteria=DetachedCriteria.forClass(Emp.class); 14 //1.2 别名 15 detachedCriteria.createAlias("dept", "d"); 16 //1.3 指定检索条件 17 Criterion criterion = Restrictions.eq("d.deptName", "开发部"); 18 //bind 绑定 19 detachedCriteria.add(criterion); 20 //detachedCriteria的方法植入对session的引入 21 22 List<Emp> list = detachedCriteria.getExecutableCriteria(session).list(); 23 24 for (Emp emp : list) { 25 System.out.println(emp.getEmpName()); 26 } 27 } 28 29 }