总结Criteria的简要使用概述(Hibernate5.2+)

一、Criteria概述

        Hibernate提出的面向对象查询API,非SQL或HQL方式。

二、Criteria使用(5.2之前版本)

        

        Criteria:标准查询接口,用来执行查询和添加条件。

        Criterion:是Criteria的查询条件,提供了add(Criterion criterion)方法添加查询条件。

        Restrictions :提供了大量的静态方法作为Criterion的条件对象。

        Projection:用于描述一个投影查询项,一个 Projection 对象就是一个投影查。

        Projections:提供了大量的静态方法用于产生 Projection 投影查询项。

        ProjectionList:多个投影查询项,是投影查询集合。可以使用add方法来添加投影查询项。

        Order:描述排序方式。

2、操作使用

        ①创建 Criteria 对象:Criteria c = session.createCriteria(Teacher.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使用示例。

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

三、Criteria使用(5.2之后版本)

1、重要API        

        CriteriaBuilder:创建查询接口的建造者类,用于创建查询接口CriteriaQuery 对象、查询条件Predicate对象、投影查询表达式Expression对象。

        CriteriaQuery:查询接口,用于添加查询条件,分组,排序,投影查询。
        Root:根据属性名称获取字段名称,字段名称可以用于查询条件和投影查询中。(from之后,可得到相应的绑定各个属性对象Path,Path是继承Expression,两者都可表达投影。)
        Predicate:条件对象。
        Expression:表达式对象,用于表达投影查询的字段,条件中的字段名称。(select之后)

2、操作使用

        ①创建查询对象:

    CriteriaBuilder criteriaBuilder = EntityManagerFactory.unwrap(SessionFactory.class).
            getCurrentSession().getCriteriaBuilder();
    CriteriaQuery<Class> criteriaQuery = criteriaBuilder.createQuery(Class c);
    Root root = criteriaQuery.from(Class c);

        ②设置查询条件(可选):

        创建查询条件:

    criteriaBuilder.equals(root.get(“字段名”), 值);	
    criteriaBuilder.and();
    criteriaBuilder.or();

        添加查询条件:

    criteriaQuery.where();

        ③ 设置投影查询(可选):

        创建投影查询项(可选):

                创建字段投影查询项:root.get(“字段名称”)

                创建聚合函数投影查询项:criteriaBuilder.avg(root.get("age"));

        添加投影查询项:

        criteriaQuery.select(投影查询项对象);
        criteriaQuery.multiselect(投影查询项对象1,投影查询项对象2...);

        ④ 设置分组(可选):criteriaQuery.groupBy(root.get(""));

        ⑤ 设置排序(可选):

                 criteriaBuilder.asc(root.get(""));//升

                 criteriaBuilder.asc(criteriaBuilder.avg(root.get("")));//根据聚合函数升序

                 criteriaBuilder.desc(root.get(""));//降

        ⑥ 封装Query对象:Query query = session.createQuery(criteriaQuery);

        ⑦ 分页查询(可选):                         

        query.setFirstResult(); 设置起始位置从0开始
        query.setMaxResult(); 设置查询总行数

        ⑧ 执行查询:

        query.getResultList();
        query.getSingleResult();

Demo:Criteria使用示例。

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]);
		}
        //8、in两种表达方式①正常条件拼接,②in的循环匹配(新),伪代码举例:查询集合为ids所有商品
        ① CriteriaBuilder builder = session.getCriteriaBuilder();
		  CriteriaQuery<Products> createQuery = builder.createQuery(Products.class);
          Root<Products> root = createQuery.from(Products.class);
          Path<Long> idPath = root.get("id");
          Predicate pre = idPath.in(ids);
          createQuery.where(pre);
          ...
        ② CriteriaBuilder builder = session.getCriteriaBuilder();
		  CriteriaQuery<Products> createQuery = builder.createQuery(Products.class);
          Root<Products> root = createQuery.from(Products.class);
          In<Long> inClause = builder.in(root.get("productIds"));//得到商品ids绑定条件
          for (Long id : ids) {
              inClause.value(id);//匹配每一个符合的id,实际in在sql的处理相当于循环匹配。
          }
          createQuery.where(inClause);
          ...
        //9、对于判断语句的拼接,可采用equal,and
          Predicate p1 = builder.equal(root.get("id"), id);
          builder.and(..., p1);
        //10、有的时候where后面条件根据判断会不存在的情况,类似... where 1=1
          Predicate p1 = builder.conjunction();
          ...
	}
}

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敬业丨小爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值