• Hibernate中QBC查询


    QBC 查询

    QBC,即 Query By Criteria,它是 Hibernate 提供的另一种查询方式,使用 HQL 查询需要写 hql 语句,但使用 QBC 查询不需要写语句,直接使用方法实现

    QBC 操作的是实体类和属性,使用 Criteria 对象实现 QBC 查询

    基本查询:

    以客户和联系人为例(一对多),下同:

    1、查询所有记录

    (1)创建 Criteria 对象

    (2)调用 Criteria 对象的方法得到结果

    /*
    * (1) 创建 Criteria 对象
    * 调用 session 的 createCriteria() 方法,参数是实体类的 class,返回值是 Criteria 类型,创建以接收
    */
    Criteria criteria=session.createCriteria(Customer.class);
    
    /*
    * (2) 调用方法得到结果
    * 调用 criteria 的 list() 方法,返回值是 List 类型,创建以接收
    */
    List<Customer> list=criteria.list();

    条件查询:

    (1)多条件查询

        /*
         * (1) 创建 Criteria 对象
         * 调用 session 的 createCriteria() 方法,参数是实体类的 class,返回值是 Criteria 类型,创建以接收
         */
        Criteria criteria = session.createCriteria(Customer.class);
        /*
         * (2) 使用 criteria 的方法设置条件
         * 调用 criteria 的 add() 方法,设置条件值,类似于 HQL 中 where cid=? and custName=?
         */
        criteria.add(Restrictions.eq("cid",1));
        criteria.add(Restrictions.eq("custName","百度"));
        /*
         * (3) 调用方法得到结果
         * 调用 criteria 的 list() 方法,返回值是 List 类型,创建以接收
         */
    
        List<Customer> list = criteria.list();

    (2)模糊查询

        /*
         * (1) 创建 Criteria 对象
         * 调用 session 的 createCriteria() 方法,参数是实体类的 class,返回值是 Criteria 类型,创建以接收
         */
        Criteria criteria = session.createCriteria(Customer.class);
    
        /*
         * (2) 使用 criteria 的方法设置条件
         * 调用 criteria 的 add() 方法,设置条件值,类似于 HQL 中 where custName like ?
         */
        criteria.add(Restrictions.like("custName","%度%"));
    
        /*
         * (3) 调用方法得到结果
         * 调用 criteria 的 list() 方法,返回值是 List 类型,创建以接收
         */
        List<Customer> list = criteria.list();

    排序查询

    /*
         * (1) 创建 Criteria 对象
         * 调用 session 的 createCriteria() 方法,参数是实体类的 class,返回值是 Criteria 类型,创建以接收
         */
        Criteria criteria = session.createCriteria(Customer.class);
    
        /*
         * (2) 设置对哪个属性进行排序以及排序规则
         */
        criteria.addOrder(Order.asc("cid"));
    
        /*
         * (3) 调用方法得到结果
         * 调用 criteria 的 list() 方法,返回值是 List 类型,创建以接收
         */
        List<Customer> list = criteria.list();

    分页查询

    /*
         * (1) 创建 Criteria 对象
         * 调用 session 的 createCriteria() 方法,参数是实体类的 class,返回值是 Criteria 类型,创建以接收
         */
        Criteria criteria = session.createCriteria(Customer.class);
    
        /*
         * (2) 设置分页数据
         * 开始位置和每页的记录数
         */
        criteria.setFirstResult(0);
        criteria.setMaxResults(10);
    
        /*
         * (3) 调用方法得到结果
         * 调用 criteria 的 list() 方法,返回值是 List 类 型,创建以接收
         */
        List<Customer> list = criteria.list();
    
        /*
         * 开始位置计算公式:(当前页 - 1) * 每页记录数
         */

    统计查询

        /*
         * (1) 创建 Criteria 对象
         * 调用 session 的 createCriteria() 方法,参数是实体类的 class,返回值是 Criteria 类型,创建以接收
         */
        Criteria criteria = session.createCriteria(Customer.class);
    
        /*
         * (2) 设置操作
         */
        criteria.setProjection(Projections.rowCount());
    
        /*
         * (3) 调用方法得到结果
         * 调用 criteria 的 uniqueResult() 方法,返回值是Object 类型,创建以接收
         */
        Object obj = criteria.uniqueResult();
    
        /*
         * 注意:不能直接把 obj 转成 int 类型,需要先转成Long 类型:
         * Long val=(Long) obj;
         * int valx=val.intValue();
         */

    离线查询

    也称离线条件查询,可以脱离 Session 而对条件进行封装

    应用场景:

    Servlet 调用 Service,Service 调用 DAO

    一般情况下,参数往往是从 Web 层传到业务层,进而传到 DAO层,最后在 DAO 层中拼接 SQL 完成查询

    有了离线查询后,就可以直接在 Web 层将数据封装好,传到业务层,进而传到 DAO 层完成查询

    使用 DetachedCriteria 对象实现离线条件查询

        /*
         * (1) 创建 DetachedCriteria 对象(离线对象)
         * 调用 DetachedCriteria 的 forClass() 静态方法,参数是实体类的 class,返回值是 DetachedCriteria类型,创建以接收
         */
        DetachedCriteria detachedCriteria=DetachedCriteria.forClass(Customer.class);
    
        /*
         * (2) 最终执行时才需要 Session
         * 调用 detachedCriteria 的 getExecutableCriteria()方法,返回值是 Criteria 类型,创建以接收
         */
        Criteria criteria=detachedCriteria.getExecutableCriteria(session);
    
        /*
         * (3) 调用方法得到结果
         * 调用 criteria 的 list() 方法,返回值是 List 类型,创建以接收
         */
        List<Customer> list=criteria.list();

    连表查询(子查询):

        //中心采购看所有,自行采购看本部门
        String deptid = demand.get("deptId");
        if(StringUtils.hasText(deptid))
        {
            criteria.createAlias("appUser", "u");
            criteria.add(Expression.eq("u.dept.id", Long.parseLong(deptid)));
            //三表:采购表,user表,dept表。appUser和dept是配的关系。
            String series = demand.get("samples.labSeries");
            if (org.springframework.util.StringUtils.hasText(series)) {
                criteria.add(Expression.sqlRestriction(" id in (select suit_Id from samples where lab_Series='" + series + "')"));
            }
        }

    实体类结构:

        Session session = sc.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Pass.class);
        criteria =criteria.createAlias("user","u");
        criteria =criteria.add(Property.forName("u.id").eq(101));
        List<Pass> list = criteria.list();
        System.out.println(list);
        transaction.commit();

    输出的最终的sql语句:

    左外连接:

        /*
         * 一对多双向关联-左外连接-QBC
         */
        @Test
        public void
        testLeft() {
            try {
                session.beginTransaction();
    
                List<Forum> list = session.createCriteria(Forum.class)
                        .createCriteria("forumPosts", JoinType.LEFT_OUTER_JOIN)
                        .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                        .list();
                for (Forum forum : list) {
                    System.out.println(forum.getName());
                }
                session.getTransaction().commit();
            } catch (Exception e) {
                session.getTransaction().rollback();
                e.printStackTrace();
            }
        }
  • 相关阅读:
    简易的观察者模式
    SSM项目实战 之 权限管理系统
    SSM项目实战 之 Shiro
    SSM项目实战 之 Maven
    SSM项目实战 之 EasyUI
    Oracle复习思路
    Oracle存储过程 函数 计算使用资源
    Mybatis笔记(二)
    Mybatis笔记(一)
    Oracle表空间 与 分页
  • 原文地址:https://www.cnblogs.com/yangjiaoshou/p/16002174.html
Copyright © 2020-2023  润新知