Criteria是Hibernate提供的一组纯面向对象的查询API. 其功能类似Query, 但完全以面向对象的形式管理查询逻辑. 更符合ORM的设计思想.
用到特定于数据库的SQL 语句,程序本身会依赖于特定的数据库,不了解SQL 语句,恐怕对使用HQL带来困难。Hibernate提供的Criteria查询帮助我们解决了这种问题。
/**
* 采用critical查询
*/
@Test
public void getAllStudent(){
//查询Student对象的所有数据
Criteria criteria = session.createCriteria(Student.class);
List<Student> list = criteria.list();
for (Student student : list) {
System.out.println(student);
}
}
条件查询
@Test
public void getStudent(){
Criteria criteria = session.createCriteria(Student.class);
/* 添加条件 - Restrictions
* 提供SQL操作的所有静态方法
* 查询名字为本兮
*/
//添加条件,eq方法
Criterion criterion = Restrictions.eq("sname", "benxi");
//添加条件到Criteria
criteria.add(criterion);
List<Student> list = criteria.list();
for (Student student : list) {
System.out.println(student);
}
}
多个条件进行查询
@Test
public void getStudent2(){
Criteria criteria = session.createCriteria(Student.class);
/* 添加条件 - Restrictions
* 提供SQL操作的所有静态方法
* 查询名字为本兮
*/
//条件或,两个中满足一个
Criterion criterion = Restrictions.or(Restrictions.eq("sname", "benxi"), Restrictions.eq("sname", "zahngfeng"));
//添加多个条件,Restrictions的and方法,
Criterion criterion = Restrictions.and(Restrictions.between("age", 12, 30),
Restrictions.and(Restrictions.eqOrIsNull("sname", "benxi"), Restrictions.eq("age", 12)));
//添加条件到Criteria
criteria.add(criterion);
List<Student> list = criteria.list();
for (Student student : list) {
System.out.println(student);
}
}
统计查询:
@Test
public void getStudent3(){
Criteria criteria = session.createCriteria(Student.class);
/* 添加条件 - Restrictions
* 提供SQL操作的所有静态方法
* 查询总人数
*/
//添加一个显示的字段
Projection p1 = Projections.count("sid");
//添加分组,相当于group by gender
Projection p2 = Projections.groupProperty("gender");
//添加条件到Criteria
criteria.setProjection(Projections.projectionList().add(p2).add(p1));
List<Object[]> list = criteria.list();
for (Object[] student : list) {
System.out.println(student[0]+"---"+student[1]);
}
}
排序查询
//如果设置了两个排序,定义在前面的为主,后面的为辅。定义相同的属性,后面的不能覆盖前面的
Criteria criteria = session.createCriteria(Student.class);
criteria.addOrder(Order.desc("age"));
criteria.addOrder(Order.desc("sid"));
List<Student> list = criteria.list();
分页:从第0条开始,查询3条数据
Criteria criteria = session.createCriteria(Student.class);
criteria.setFirstResult(0).setMaxResults(3);
List<Student> list = criteria.list();
条件查询:提供一个关键字,查询数据
Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.like("sname", "n", MatchMode.ANYWHERE));
//效果等同于
//criteria.add(Restrictions.like("sname", "%n%"));
List<Student> list = criteria.list();
QBC常用限定方法
Restrictions.eq –> equal,等于.
Restrictions.allEq –> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq 的效果
Restrictions.gt –> great-than > 大于
Restrictions.ge –> great-equal >= 大于等于
Restrictions.lt –> less-than, < 小于
Restrictions.le –> less-equal <= 小于等于
Restrictions.between –> 对应SQL的between子句
Restrictions.like –> 对应SQL的LIKE子句
Restrictions.in –> 对应SQL的in子句
Restrictions.and –> and 关系
Restrictions.or –> or 关系
Restrictions.isNull –> 判断属性是否为空,为空则返回true 相当于SQL的 is null
Restrictions.isNotNull –> 与isNull相反 相当于SQL的 is not null
Restrictions.sqlRestriction –> SQL限定的查询
Order.asc –> 根据传入的字段进行升序排序
Order.desc –> 根据传入的字段进行降序排序
MatchMode.EXACT –> 字符串精确匹配.相当于”like ‘value’”
MatchMode.ANYWHERE –> 字符串在中间匹配.相当于”like ‘%value%’”
MatchMode.START –> 字符串在最前面的位置.相当于”like ‘value%’”
MatchMode.END –> 字符串在最后面的位置.相当于”like ‘%value’”
另外再写一种实现方式:离线查询,一般我们进行web开发都会碰到多条件查询。例如根据条件搜索。条件的多少 逻辑关系 是or 还是and等等。我们要根据这些条件来拼写查询语句。
但是有了离线查询这些都不是问题,我们可以使用DetachedCriteria来构造查询条件,然后将这个DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后,可以在session范围内直接构造Criteria,进行查询。就此,查询语句的构造完全被搬离到web层实现,而业务层则只负责完成持久化和查询的封装即可。换句话说,业务层代码是不变化的。我们不必为了查询条件的变化而去频繁改动查询语句了
离线查询:
@Test
public void crud(){
DetachedCriteria detached = DetachedCriteria.forClass(Student.class);
Criteria criteria = detached.getExecutableCriteria(session);
List<Student> list = criteria.list();
for (Student student : list) {
System.out.println(student);
}
}