一、Criteria 查询
1、Criteria 查询概述
(1)Criteria 是 Hibernate 提出的纯粹的面向对象的查询方式,在使用 Criteria 查询数据时,不需要书写任何一个SQL语句或者HQL语句,即时是一个完全不懂SQL的人,也完全可以使用 Criteria 所提供的的各种API来设置查询条件、分页、排序、联合查询等等,也依然可以使用 Criteria 查询出想要的数据。
2、Criteria 5.2 以前的API和使用
(1)Criteria 重要API(5.2以前)
Criteria(5.2版本以前)
:标准查询接口,通过该接口来执行查询、添加条件等等。Criterion
:Criterion 是 Criteria 的查询条件。Criteria 提供了add(Criterion criterion)
方法来
添加查询条件。Restrictions
:Restrictions 类中提供了大量的静态方法用于产生 Criterion 条件对象Projection
:Projection 用来描述一个投影查询项,一个 Projection 对象就是一个投影查询项ProjectionList
:ProjectionList 是投影查询集合,用来描述多个投影查询项,可以使用add方法添加投影查询项Projections
:Projections 类中提供了大量的静态方法用于产生 Projection 投影查询项Order
:描述排序方式
(2)Criteria 使用过程(5.2以前):
① 创建 Criteria 对象:
Criteria cri=session.createCriteria(Student.class);
参数:表示需要查询表对应的的实体类
② 设置查询条件:(可选)
-
使用 Restrictions 的静态方法可以快速生成查询条件对象 Criterion
Restrictions.eq
:equal,等于
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.isNull
: 判断属性是否为空,为空则返回 true
Restrictions.and
:and 关系
Restrictions.or
:or 关系 -
查询条件对象定义好之后需要将查询条件添加到 Criteria 对象中
criteria.add(查询条件对象)
③ 设置投影查询项:(可选)
-
创建投影查询项:
Projections.property("属性名")
:创建一个投影查询项为一个属性的 Projection 对象
Projections.avg(String propertyName)
:求平均值的投影查询对象
Projections.count(String propertyName)
:求属性出现次数总和的投影查询对象
Projections.max(String propertyName)
:求属性最大值的投影查询对象
Projections.min(String propertyName)
:求最小值的投影查询对象
Projections.sum(String propertyName)
:求和的投影查询对象
Projections.聚合函数(String propertyName,”别名”)
:当我们要使用聚合函数的结果来排序时,可以给聚合函数的投影结果定义别名,最后通过该别名来实现排序
Projections.聚合函数(String propertyName).as(”别名”)
:当我们要使用聚合函数的结果来排序时,可以给聚合函数的投影结果定义别名,最后通过该别名来实现排序
Projections.projectionList()
:创建一个投影查询对象集合,一个集合可以保存多个投影查询项对象
projectionList.add(Projection对象)
:将投影查询对象添加到投影查询集合中
projectionList.add(Projection对象,字符串)
:将投影查询对象添加到查询集合中,并为其添加别名
Projections.groupProperty(String propertyName)
:分组 -
将投影查询项设置 Criteria 中
criteria.setProjection(Projection对象)
④ 设置排序方式:(可选)
criteria.addOrder(Order.asc(“属性名或者别名”)):升序
criteria.addOrder(Order.desc(“属性名或者别名”)):降序
⑤ 设置分页:(可选)
criteria.setFirstResult(); 设置起始位置从0开始
criteria.setMaxResult(); 设置查询总行数
⑥ 执行查询
criteria.list();
criteria.uniqueResult();
Demo:criteria 示例1
public class CriteriaDemo {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
Session session = SessionUtil.openConnection();
//1、查询所有数据
Criteria criteria = session.createCriteria(Products.class);
List<Products> list0 = criteria.list();
System.out.println(list0);
//2、条件查询:单个条件
Criteria criteria1 = session.createCriteria(Products.class);
Criterion lt = Restrictions.lt("p_name", "M416");
criteria1.add(lt);
System.out.println(criteria1.list());
//3、条件查询:多个条件之and
Criteria criteria2 = session.createCriteria(Products.class);
Criterion lt2 = Restrictions.lt("p_count", 2000);
Criterion gt2 = Restrictions.gt("p_price", 2000.0);
//创建and条件对象
Criterion c = Restrictions.and(lt2, gt2);
criteria2.add(c);
System.out.println(criteria2.list());
//4、条件查询:多个条件之or
Criteria criteria3 = session.createCriteria(Products.class);
Criterion lt3 = Restrictions.lt("p_count", 2000);
Criterion gt3 = Restrictions.gt("p_price", 2000.0);
//创建and条件对象
Criterion c1 = Restrictions.or(lt3, gt2);
criteria3.add(c1);
System.out.println(criteria3.list());
//5、查询所有商品的名字
Criteria criteria4 = session.createCriteria(Products.class);
Projection name = Projections.property("p_name");
criteria4.setProjection(name);
System.out.println(criteria4.list());
//6、查询数据总行数
Criteria criteria5 = session.createCriteria(Products.class);
CountProjection count_id = Projections.count("p_id");
criteria5.setProjection(count_id);
System.out.println(criteria5.uniqueResult());
//7、查询商品名称、价格,并根据价格排序
Criteria criteria6 = session.createCriteria(Products.class);
Projection name1 = Projections.property("p_name");
Projection price1 = Projections.property("p_price");
ProjectionList projectionList = Projections.projectionList();
projectionList.add(name1);
projectionList.add(price1);
criteria6.setProjection(projectionList);
List<Object[]> list = (List<Object[]>)criteria6.list();
criteria6.addOrder(Order.desc("p_price"));
for(Object[] o: list) {
System.out.println(o[0] + ":" + o[1]);
}
//8、根据类型分组,求每种类型的商品数量,并按照数量降序排列
Criteria criteria7 = session.createCriteria(Products.class);
//分组
PropertyProjection groupProperty = Projections.groupProperty("p_typeid");
//投影
Projection count = Projections.count("p_id");
ProjectionList projectionList1 = Projections.projectionList();
projectionList1.add(groupProperty);
//添加投影时,要给投影项取别名
projectionList1.add(count,"count");
criteria7.setProjection(projectionList1);
//排序
criteria7.addOrder(Order.desc("count"));
List<Object[]> list1 = (List<Object[]>)criteria7.list();
for(Object[] o: list1) {
System.out.println(o[0]+":"+o[1]);
}
//9、分页查询
Criteria criteria8=session.createCriteria(Products.class);
criteria8.setFirstResult(1);
criteria8.setMaxResults(2);
System.out.println(criteria8.list());
session.close();
}
}
3、Criteria 5.2 以后的API和使用
(1)Criteria 重要API(5.2以后)
CriteriaQuery
:查询接口,用于添加查询条件,分组,排序,投影查询CriteriaBuilder
:创建查询接口的建造者类,用于创建 CriteriaQuery 对象、查询条件对象、投影查询表达式对象Root
:根据属性名称获取字段名称,字段名称可以用于查询条件和投影查询中Predicate
:条件对象Expression
:表达式对象,用于表达投影查询的字段,条件中的字段名称
(2)Criteria 使用过程(5.2以后):
① 创建查询对象
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Class> criteriaQuery = criteriaBuilder.createQuery(Class c);
Root root=criteriaQuery.from(Class c);
注意:在创建查询接口 CriteriaQuery 时,可以指定最终查询出的数据类型,定义好之后后续查询出的数据不需要在进行强转。
② 设置查询条件(可选)
1)创建查询条件:
criteriaBuilder.equals(root.get(“字段名”),值);
criteriaBuilder.and();
criteriaBuilder.or();
3)添加查询条件
criteriaQuery.where();
③ 设置投影查询(可选):
1)创建投影查询项:
创建字段投影查询项:
root.get(“字段名称”)
创建聚合函数投影查询项
criteriaBuilder.avg(root.get("age"));
2)添加投影查询项:
criteriaQuery.select(投影查询项对象);
criteriaQuery.multiselect(投影查询项对象1,投影查询项对象2...);
④ 设置分组(可选):
criteriaQuery.groupBy(root.get(""));
⑤ 设置排序(可选):
1)创建排序对象:
根据字段升序:
criteriaBuilder.asc(root.get(""));
根据聚合函数升序:
criteriaBuilder.asc(criteriaBuilder.avg(root.get("")));
根据字段降序:
criteriaBuilder.desc(root.get(""));
根据聚合函数降序:
criteriaBuilder.desc(criteriaBuilder.avg(root.get("")));
2)添加排序:
criteriaQuery.orderBy();
⑥ 封装Query对象:
Query query=session.createQuery(criteriaQuery);
⑦ 分页查询(可选):
query.setFirstResult(); 设置起始位置从0开始
query.setMaxResult(); 设置查询总行数
⑧ 执行查询:
query.getResultList();
query.getSingleResult();
同样的,投影查询的单个结果以 Object 封装,多个结果用 Object 数组封装
Demo:criteria 示例2
public class QBCQuery {
public static void main(String[] args) {
Session session = SessionUtil.openConnection();
//1、查询所有数据
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Products> createQuery = builder.createQuery(Products.class);
Root<Products> root = createQuery.from(Products.class);
//执行查询
Query<Products> query = session.createQuery(createQuery);
List<Products> list = query.list();
System.out.println(list);
//2、条件查询:单个条件
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Products> createQuery = builder.createQuery(Products.class);
Root<Products> root = createQuery.from(Products.class);
//创建条件
Path path = root.get("p_price");
Predicate price = builder.lt(path, 2000.0);
createQuery.where(price);
//执行查询
Query<Products> query = session.createQuery(createQuery);
List<Products> list = query.list();
System.out.println(list);
//3、条件查询:多个条件
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Products> createQuery = builder.createQuery(Products.class);
Root<Products> root = createQuery.from(Products.class);
//创建条件
Path<Double> price = root.get("p_price");
Path<Integer> count = root.get("p_count");
Predicate pricelt = builder.lt(price, 2000.0);
Predicate countgt = builder.gt(count, 200);
Predicate predicate = builder.and(pricelt,countgt);
createQuery.where(predicate);
//执行查询
Query<Products> query = session.createQuery(createQuery);
List<Products> list = query.list();
System.out.println(list);
//4、投影查询:查询单个属性(查询所有商品的名称)
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<String> createQuery = builder.createQuery(String.class);
Root<Products> root = createQuery.from(Products.class);
//创建查询条件
Expression<String> name = root.get("p_name");
createQuery.select(name);
//执行查询
Query<String> query = session.createQuery(createQuery);
List<String> list = query.list();
System.out.println(list);
//5、投影查询:查询多个属性(查询所有商品的名称和价格)
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Object[]> createQuery = builder.createQuery(Object[].class);
Root<Products> root = createQuery.from(Products.class);
//创建查询条件
Expression<String> name = root.get("p_name");
Expression<Double> price = root.get("p_price");
createQuery.multiselect(name,price);
//执行查询
Query<Object[]> query = session.createQuery(createQuery);
List<Object[]> list = query.list();
for(Object[] row: list) {
System.out.println(row[0] + ":" + row[1]);
}
//6、投影查询:查询多个属性(查询所有商品的名称和价格,加上条件)
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Object[]> createQuery = builder.createQuery(Object[].class);
Root<Products> root = createQuery.from(Products.class);
//创建查询条件
Expression<String> name = root.get("p_name");
Expression<Double> price = root.get("p_price");
Expression<Double> max = builder.max(price);
createQuery.multiselect(name,max);
//执行查询
Query<Object[]> query = session.createQuery(createQuery);
List<Object[]> list = query.list();
for(Object[] row: list) {
System.out.println(row[0] + ":" + row[1]);
}
//7、分组、统计、排序
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Object[]> createQuery = builder.createQuery(Object[].class);
Root<Products> root = createQuery.from(Products.class);
//分组
createQuery.groupBy(root.get("p_typeid"));
//统计
Expression<Long> count = builder.count(root.get("p_id"));
//条件
Predicate gt = builder.gt(count, 3); //统计数量大于3的
createQuery.having(gt);
Path<Object> pTypeid = root.get("p_typeid");
createQuery.multiselect(count, pTypeid);
//排序
createQuery.orderBy(builder.asc(count));
//执行查询
Query<Object[]> query = session.createQuery(createQuery);
List<Object[]> list = query.list();
for(Object[] row: list) {
System.out.println(row[0] + ":" + row[1]);
}
}
}