zoukankan      html  css  js  c++  java
  • Hibernate框架的学习--第四天

    一、 Hibernate查询高级

        1. 查询总结

            1.oid查询-get

           2.对象属性导航查询

           3.HQL

           4.Criteria

           5.原生SQL

       2. 查询-HQL语法

            1)基础语法      

       /**
         * 基本语法
         */
        @Test
        public void fun1() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql1 = "from com.java.domain.Customer"; //完整写法  
            String hql2 = "from Customer"; //简单写法
            //2>创建查询的对象
            Query query = session.createQuery(hql2);
            //3>执行查询操作
            List<Customer> list = query.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      2)排序     

      /**
         * 排序查询
         * 
         */
        @Test
        public void fun2() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql1 = "from Customer order by cust_id desc"; //降序查询
            String hql2 = "from Customer order by cust_id asc"; //升序查询
            //2>创建查询的对象
            Query query = session.createQuery(hql2);
            //3>执行查询操作
            List<Customer> list = query.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      3)条件查询

              ?占位符和命名占位符 

      /**
         * 条件查询
         * ?占位符
         * 命名占位符
         */
        @Test
        public void fun3() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql1 = "from Customer where cust_id=?"; //简单写法
            String hql2 = "from Customer where cust_id=:cust_id";
            //2>创建查询的对象
            Query query = session.createQuery(hql2);
            
            //设置查询的参数
            //query.setParameter(0, 1l);
            query.setParameter("cust_id", 1l);
            //3>执行查询操作
            List<Customer> list = query.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      4)分页查询        

          limit ?,?
         query.setFirstResult(2);
         query.setMaxResults(2); 

        /**
         * 分页查询
         * limit ?,?
         *    query.setFirstResult(2);
         *    query.setMaxResults(2);
         */
        @Test
        public void fun4() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql = "from Customer"; //简单写法
            //2>创建查询的对象
            Query query = session.createQuery(hql);
            
            //limit ?,?
            query.setFirstResult(2);
            query.setMaxResults(2);
            
            //3>执行查询操作
            List<Customer> list = query.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      5)统计检索(聚合函数)

      /**
         * 统计检索(聚合函数)
         *    
         */
        @Test
        public void fun5() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql1 = "select count(*) from Customer"; //简单写法
            String hql2 = "select sum(cust_id) from Customer"; //简单写法
            String hql3 = "select avg(cust_id) from Customer"; //简单写法
            String hql4 = "select min(cust_id) from Customer"; //简单写法
            String hql5 = "select max(cust_id) from Customer"; //简单写法
            //2>创建查询的对象
            Query query = session.createQuery(hql5);
            
            //3>执行查询操作
            Number result = (Number) query.uniqueResult();
            System.out.println(result);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      6)投影查询

      /**
         * 投影查询
         *    
         */
        @Test
        public void fun6() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql1 = "select cust_id from Customer"; //简单写法
            String hql2 = "select cust_id,cust_name from Customer"; //简单写法
            String hql3 = "select new Customer(cust_id, cust_name) from Customer"; //简单写法
            //2>创建查询的对象
            Query query = session.createQuery(hql3);
            
            //3>执行查询操作
            List list = query.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      7)多表查询

            

         1) 原生SQL

            交叉连接-笛卡尔积(避免)
           select * from A,B
           内连接
                |-隐式内连接
        select * from A,B where B.aid=A.aid
           |-显式内连接
              select * from A inner join B on B.aid=A.aid
      外连接
        |-左外连接
        select * from A left [outer] B on B.aid=A.aid
           |-右外连接
        select * from A right [outer] B on B.aid=A.aid

        2)HQL的多表查询

       内连接(迫切)
       外连接
          |-左外(迫切)
          |-右外(迫切)

        3)HQL多表查询的案例

    public class Demo02 {
        /**
         * 内连接
         * 将连接两端的对象分别返回放入数组
         */
        @Test
        public void fun1() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql = "from Customer c inner join c.linkMens"; //完整写法  
            //2>创建查询的对象
            Query query = session.createQuery(hql);
            //3>执行查询操作
            List<String[]> list = query.list();
            for(Object[] obj : list) {
                System.out.println(Arrays.toString(obj));
            }
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 内连接迫切
         * 将两端的对象封装成一个对象返回
         * from Customer c inner join c.linkMens
         */
        @Test
        public void fun2() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql = "from Customer c inner join fetch c.linkMens"; //完整写法  
            //2>创建查询的对象
            Query query = session.createQuery(hql);
            //3>执行查询操作
            List<Customer> list = query.list();
            for(Customer c : list) {
                System.out.println(c);
            }
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 左外连接
         * 将连接两端的对象分别返回并放到数组中
         * from Customer c left join c.linkMens
         */
        @Test
        public void fun3() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql = "from Customer c left join c.linkMens"; //完整写法  
            //2>创建查询的对象
            Query query = session.createQuery(hql);
            //3>执行查询操作
            List<Object[]> list = query.list();
            for(Object[] obj : list) {
                System.out.println(Arrays.toString(obj));
            }
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        
        /**
         * 右外连接
         * 将连接两端的对象分别返回并放到数组中
         * from Customer c right join c.linkMens
         */
        @Test
        public void fun4() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>定义hql语句
            String hql = "from Customer c right join c.linkMens"; //完整写法  
            //2>创建查询的对象
            Query query = session.createQuery(hql);
            //3>执行查询操作
            List<Object[]> list = query.list();
            for(Object[] obj : list) {
                System.out.println(Arrays.toString(obj));
            }
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }  
    }

      3. 查询-Criteria语法

       1)基本知识

               QBC(Query By Criteria)是hibernate提高的另一种检索对象的方式,它主要由Criteria接口Criterion接口和Expression类组成。Criteria接口是Hibernate API中的一个查询接口,它需由session进行创建。Criterion是Criteria的查询条件,在Criteria中提供了add(Criterion criterion)方法来添加查询条件。使用QBC检索对象的示例代码如下:     

        //1>创建ceriteria对象
            Criteria criteria = session.createCriteria(Customer.class);
            
            //2>添加查询条件
            //criteria.add(Restrictions.idEq(1l));
            criteria.add(Restrictions.eq("cust_id", 1l));
            //3>执行查询
            List<Customer> list = criteria.list();

      QBC检索是使用Restrictions对象编写查询条件的,在Restrictions类中提供了大量的静态方法来创建查询条件,其常用的方法如表所示:                  

              

      2)基本查询

        /**
         * 基本语法
         */
        @Test
        public void fun1() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>创建ceriteria对象
            Criteria criteria = session.createCriteria(LinkMan.class);
            
            //2>执行查询
            List<LinkMan> list = criteria.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      2)条件查询

      /**
         * 条件查询
         */
        @Test
        public void fun2() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>创建ceriteria对象
            Criteria criteria = session.createCriteria(Customer.class);
            
            //2>添加查询条件
            //criteria.add(Restrictions.idEq(1l));
            criteria.add(Restrictions.eq("cust_id", 1l));
            //3>执行查询
            List<Customer> list = criteria.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      3)分页查询

    /**
         * 分页查询
         * limit ?,?
         * criteria.setFirstResult(0);
         * criteria.setMaxResults(2);
         */
        @Test
        public void fun3() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>创建ceriteria对象
            Criteria criteria = session.createCriteria(Customer.class);
            
            //2>设置分页查询的参数 limit ?,?
            criteria.setFirstResult(0);
            criteria.setMaxResults(2);
            
            //3>执行查询
            List<Customer> list = criteria.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }

      4)排序查询

    /**
         * 排序查询
         *  criteria.addOrder(Order.asc("cust_id")); //升序查询
         *    criteria.addOrder(Order.desc("cust_id")); //降序查询
         */
        @Test
        public void fun4() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>创建ceriteria对象
            Criteria criteria = session.createCriteria(Customer.class);
            
            //2>添加排序条件
            //criteria.addOrder(Order.asc("cust_id")); //升序查询
            criteria.addOrder(Order.desc("cust_id")); //降序查询
            
            //3>执行查询
            List<Customer> list = criteria.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
        }

      5)统计查询

    /**
         * 统计查询
         * 总记录数 
         * criteria.setProjection(Projections.rowCount());
         */
        @Test
        public void fun5() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            //1>创建ceriteria对象
            Criteria criteria = session.createCriteria(Customer.class);
            
            //2>设置查询目标  总记录数
            criteria.setProjection(Projections.rowCount());
            
            //3>执行查询
            List<Customer> list = criteria.list();
            System.out.println(list);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
        }

      4. 查询优化

     1)类级别查询

            get方法:没有任何策略.调用即立即查询数据库加载数据.

           load方法: 应用类级别的加载策略       

      懒加载 延迟加载
       load()方法(默认):是在执行时,不会发送任何sql语句,通过动态代理返回一个对象,
      在对象使用的时候,才执行查询

       延迟加载:仅仅获得没有使用,不会查询。在使用时,才进行查询
       是否对类延迟加载可以通过在class元素上配置lazy属性
       lazy(默认):true 加载时不查询,使用时才查询
       lazy:false load方法与get方法没有任何区别 加载时立即查询

      为了提高效率建议使用懒加载

    public class Demo {
        /**
         * get()方法:立即加载。执行方法时立即发送sql语句查询结果
         */
        @Test
        public void fun1() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            Customer c = session.get(Customer.class, 2l);
            System.out.println(c);
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        
        /**
         * load()方法(默认):是在执行时,不会发送任何sql语句,通过动态代理返回一个对象,
         *                     在对象使用的时候,才执行查询
         * 延迟加载:仅仅获得没有使用,不会查询。在使用时,才进行查询
         * 是否对类延迟加载可以通过在class元素上配置lazy属性
         *  lazy(默认):true   加载时不查询,使用时才查询
         *  lazy:false  加载时立即查询
         */
        @Test
        public void fun2() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            Customer c = session.load(Customer.class, 2l);
            System.out.println(c);
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
        }
        
        
    }

      2)关联级别查询

              1. 集合策略

           lazy属性:决定是否延迟加载
            true(默认值):延迟加载,懒加载
              false:立即加载
            extra:及其懒惰
           fetch属性:决定加载策略,使用什么类型的sql语句加载集合数据
                    select(默认值):单表查询加载
               join:使用多表查询加载集合
               subselect:使用子查询加载查询集合           

    /**
     * 
     *  关联级别  延迟加载
     *  集合级别的关联
     * @author vanguard
     *
     */
    public class Demo {
        /**
         * 集合级别的关联
         * fetch:select  单表查询
         * lazy:true 延迟加载  使用时才加载集合数据
         */
        @Test
        public void fun1() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            Customer c = session.get(Customer.class, 2l);
            
            Set<LinkMan> linkMens = c.getLinkMens(); //关联级别
            
            System.out.println(linkMens);
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 集合级别的关联
         * fetch:select  单表查询
         * lazy:false 立即加载数据
         */
        @Test
        public void fun2() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            Customer c = session.get(Customer.class, 2l);
            
            Set<LinkMan> linkMens = c.getLinkMens(); //关联级别
            
            System.out.println(linkMens);
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 集合级别的关联
         * fetch:select  单表查询
         * lazy:extra 极其懒惰
         * 与懒加载效果基本一致. 如果只获得集合的size.只查询集合的size(count语句)
         */
        @Test
        public void fun3() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            Customer c = session.get(Customer.class, 2l);
            
            Set<LinkMan> linkMens = c.getLinkMens(); //关联级别
            
            System.out.println(linkMens.size());
            
            System.out.println(linkMens);
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 集合级别的关联
         * fetch:join 使用多表查询加载集合数据
         * lazy:true|false|extra失效  立即加载
         */
        @Test
        public void fun4() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            Customer c = session.get(Customer.class, 2l);
            
            Set<LinkMan> linkMens = c.getLinkMens(); //关联级别
            
            System.out.println(linkMens.size());
            
            System.out.println(linkMens);
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 集合级别的关联
         * fetch:subselect 使用子查询加载集合数据
         * lazy:true  延迟加载
         */
        @Test
        public void fun5() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            String hql = "from Customer";
            
            Query query = session.createQuery(hql);
            
            List<Customer> list = query.list();
            
            for(Customer c : list) {
                System.out.println(c.getLinkMens());
            }
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 集合级别的关联
         * fetch:subselect 使用子查询加载集合数据
         * lazy:false  立即加载加载
         */
        @Test
        public void fun6() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            String hql = "from Customer";
            
            Query query = session.createQuery(hql);
            
            List<Customer> list = query.list();
            
            for(Customer c : list) {
                System.out.println(c.getLinkMens());
            }
               
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 集合级别的关联
         * fetch:subselect 使用子查询加载集合数据
         * lazy:extra  极其懒惰加载
         */
        @Test
        public void fun7() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            String hql = "from Customer";
            
            Query query = session.createQuery(hql);
            
            List<Customer> list = query.list();
            
            for(Customer c : list) {
                System.out.println(c.getLinkMens().size());
                System.out.println(c.getLinkMens());
            }
            
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
    }

        2. 关联属性策略     

         fetch属性 决定加载的sql语句
          select:使用单表查询
          join:使用多表查询
         lazy:决定加载时机
          false:立即加载
          proxy:有customer的类级别加载策略决定

             

    /**
     * 
     *  关联级别  延迟加载
     *  属性策略
     * @author vanguard
     *
     */
    public class Demo02 {
        /**
         * 
         * fetch:select  单表查询
         * lazy:proxy 
         *   Customer--true 
         */
        @Test
        public void fun1() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            LinkMan linkMan = session.get(LinkMan.class, 1l);
            
            Customer customer = linkMan.getCustomer();
            
            System.out.println(customer);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 
         * fetch:select  单表查询
         * lazy:proxy 
         *   Customer--false 立即加载 
         */
        @Test
        public void fun2() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            LinkMan linkMan = session.get(LinkMan.class, 1l);
            
            Customer customer = linkMan.getCustomer();
            
            System.out.println(customer);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        /**
         * 
         * fetch:join  多表查询
         * lazy:proxy 失效  都是立即加载
         */
        @Test
        public void fun3() {
            //1. 获得session
            Session session = HibernateUtils.getSession();
            //2. 开启事务并获得操作事务的对象
            Transaction tx = session.beginTransaction();
            //3. 执行操作
            
            LinkMan linkMan = session.get(LinkMan.class, 1l);
            
            Customer customer = linkMan.getCustomer();
            
            System.out.println(customer);
            
            //4. 提交事务并释放资源
            tx.commit();
            session.close();
            
        }
        
    }

       结论:为了提高效率.fetch的选择上应选择select. lazy的取值应选择 true. 全部使用默认值.

         4. no-session问题解决:

           扩大session的作用域

             

       3)批量抓取

               betch-size:值是抓取集合的数量

              抓取客户的集合时,一次抓取集合客户的联系人

  • 相关阅读:
    mysql "The user specified as a definer ('root'@'%') does not exist" 问题
    mysql添加Federated引擎问题
    D7经典脚本[multi/handler]
    redhat7.4安装vertica-9.1.0教程
    批量在当前目录下所有的文件中添加指定字段
    mysql 水平分表技术
    linux普通用户提权
    两步完成利用procdump64+mimikatz获取win用户密码
    hibernate中对象的三种状态分析
    Hibernate 入门案例
  • 原文地址:https://www.cnblogs.com/guodong-wang/p/7511304.html
Copyright © 2011-2022 走看看