码迷,mamicode.com
首页 > Web开发 > 详细

八 Hibernate延迟加载&抓取策略(优化)

时间:2019-01-24 13:15:56      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:select查询   col   ESS   none   方法   加载   action   proxy   alt   

面试:Hibernate效率很低,如何优化?

缓存怎么弄的,语句怎么优化?

聊聊一级缓存,聊聊抓取策略和延迟加载,聊聊批量抓取

延迟加载:

一般不单独使用,和延迟加载一起使用

延迟加载:lazy(懒加载)

执行到该行代码的时候不会发送语句,真正使用这个对象的属性的时候才会发送sql语句进行查询。

  • 类级别延迟加载:指的是是通过load方法查询某个对象的时候是否采用延迟,通过class标签上的lazy来配置。
          • 让类级别延迟加载失效:1 lazy设为false 2 final修饰 3 调用Hibernate.initialize
  • 关联级别的延迟加载:指的是查询某个对象的关联对象的时候,是否采用延迟加载。session.get(Customer.class,1l) ,  customer.getLinkMans();
          • 抓取策略往往和关联级别的延迟加载一起使用,优化语句

类级别延迟加载配置:默认为true

技术分享图片

 

 

关联级别的延迟加载配置:在映射文件被关联的对象上配置

 技术分享图片

 

抓取策略:

通过一个对象抓取到关联对象需要发送sql语句,sql语句如何发送,发送成什么格式通过策略进行配置

  • 通过<set> 或者发送一条子查询上通过fetch属性进行设置
  • fetch和这些标签上的lazy如何设置优化发送的语句

 

<set>上的fetch和lazy

fetch:抓取策略,控制sql语句格式

  • select:  默认值,发送普通select语句,查询关联对象,至少交互两次
  • join:   发送迫切左外连接查询关联,与数据库交互一次,发一条数据
  • subselect:发送一条子查询查询关联对象

lazy:延迟加载,控制查询关联对象的时候是否采用延迟

  • true:默认值,查询关联对象默认采用延迟加载
  • false:查询关联对象不采用延迟加载
  • extra :极其懒惰。

在实际开发中,一般都采用默认值。如果有特殊需求,可能配置join

各种配置的区别测试:

/**
 * 在<set>上的fetch和lazy
 */
public class HibernateDemo4 {
    @Test
    /**
     * 默认情况
     */
    public void demo1() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查询1号客户
        Customer customer = session.get(Customer.class, 1l);// 发送一条查询客户的sql
        System.out.println(customer.getCust_name());
        // 查看1号客户每个联系人的信息
        for (LinkMan linkMan : customer.getLinkMans()) {// 发送一条根据客户查询联系人的sql
            System.out.println(linkMan.getLkm_name());
        }
        transaction.commit();
    }

    @Test
    /**
     * 设置fetch=select,lazy = true
     */
    public void demo2() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查询1号客户
        Customer customer = session.get(Customer.class, 1l);// 发送一条查询客户的sql
        System.out.println(customer.getCust_name());
        // 查看1号客户每个联系人的信息
        for (LinkMan linkMan : customer.getLinkMans()) {// 发送一条根据客户查询联系人的sql
            System.out.println(linkMan.getLkm_name());
        }
        transaction.commit();
    }

    @Test
    /**
     * 设置fetch=select,lazy =false
     */
    public void demo3() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查询1号客户
        Customer customer = session.get(Customer.class, 1l);// 不延迟,直接发送两条语句,查询客户的sql,根据客户查询联系人的sql
        System.out.println(customer.getCust_name());
        System.out.println(customer.getLinkMans().size());// 发送一条select
                                                            // count(lkm_id)
                                                            // from

        transaction.commit();
    }

    @Test
    /**
     * 设置fetch=select,lazy =extra
     */
    public void demo4() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查询1号客户
        Customer customer = session.get(Customer.class, 1l);// 发送一条查询客户语句
        System.out.println(customer.getCust_name());

        System.out.println(customer.getLinkMans().size());// 发送一条select
                                                            // count(lkm_id)
                                                            // from
        transaction.commit();
    }

    @Test
    /**
     * 设置fetch=join,lazy =失效
     */
    public void demo5() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查询1号客户
        Customer customer = session.get(Customer.class, 1l);// 发送一条迫切左外连接语句,两表全查
        System.out.println(customer.getCust_name());

        System.out.println(customer.getLinkMans().size());// 不发语句
        transaction.commit();
    }

    @Test
    /**
     * 设置fetch=subselect,lazy =true
     */
    public void demo6() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查询1号客户
        List<Customer> list = session.createQuery("from Customer").list();// 发送查询所有客户的sql语句
        for (Customer customer : list) {
            System.out.println(customer.getCust_name());
            System.out.println(customer.getLinkMans().size());// 发送一条子查询
        }
        transaction.commit();
    }

    @Test
    /**
     * 设置fetch=subselect,lazy =false
     */
    public void demo7() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 查询1号客户
        List<Customer> list = session.createQuery("from Customer").list();// 发送查询所有客户的sql语句,发送一条子查询
        for (Customer customer : list) {
            System.out.println(customer.getCust_name());
            System.out.println(customer.getLinkMans().size());
        }
        transaction.commit();
    }

}

 

 

 

<many-to-one>上的fetch和lazy

fetch:抓取策略

  • select:默认值,发送普通sql查询关联对象
  • join:发送迫切左外连接

lazy:延迟加载,控制查询关联对象的时候是否采用延迟

  • proxy:默认值,具体的取值和另一端<class>上lazy的值相同
  • false:查询关联对象,不采用延迟
  • no-proxy(不会使用)

一般使用默认值

各种配置的区别测试:

/**
 * 在<many-to-one>上的fetch和lazy
 */
public class HibernateDemo5 {
    @Test
    /**
     * 默认情况
     */
    public void demo1() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        LinkMan linkMan = session.get(LinkMan.class, 1l);// 发送一条查询联系人的语句
        System.out.println(linkMan.getLkm_name());
        System.out.println(linkMan.getCustomer());// 发送一条select查询联系人所关联的客户的语句
        transaction.commit();
    }

    @Test
    /**
     * fetch = "select" lazy = "proxy",默认值
     */
    public void demo2() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        LinkMan linkMan = session.get(LinkMan.class, 1l);// 发送一条查询联系人的语句
        System.out.println(linkMan.getLkm_name());
        System.out.println(linkMan.getCustomer());// 发送一条select查询联系人所关联的客户的语句
        transaction.commit();
    }

    @Test
    /**
     * fetch = "select" lazy = "false"
     */
    public void demo3() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        LinkMan linkMan = session.get(LinkMan.class, 1l);// 不延迟,发送一条查询联系人的语句,发送一条select查询联系人所关联的客户的语句
        System.out.println(linkMan.getLkm_name());
        System.out.println(linkMan.getCustomer());
        transaction.commit();
    }

    @Test
    /**
     * fetch = "join" lazy = 失效
     */
    public void demo4() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        LinkMan linkMan = session.get(LinkMan.class, 1l);// 发送一条迫切左外连接,两表全查
        System.out.println(linkMan.getLkm_name());
        System.out.println(linkMan.getCustomer());
        transaction.commit();
    }

}

 

批量抓取:

批量抓取:一批关联对象一起抓取,batch-size,

/**
 * Hibernate批量抓取
 */
public class HibernateDemo6 {
    @Test
    /**
     * 获取客户的时候批量抓取联系人,在Customer.hbm.xml中设置set标签batch-size="4"
     */
    public void demo1() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        List<Customer> list = session.createQuery("from Customer").list();
        for (Customer customer : list) {
            System.out.println(customer.getCust_name());
            for (LinkMan linkMan : customer.getLinkMans()) {
                System.out.println(linkMan.getLkm_name());
            }
        }
        transaction.commit();
    }

    @Test
    /**
     * 获取联系的时候批量抓取客户,在Customer.hbm.xml中设置class标签batch-size="4"
     */
    public void demo2() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        List<LinkMan> list = session.createQuery("from LinkMan").list();
        for (LinkMan linkMan : list) {
            System.out.println(linkMan.getLkm_name());
            System.out.println(linkMan.getCustomer().getCust_name());
        }
        transaction.commit();
    }
}

 

八 Hibernate延迟加载&抓取策略(优化)

标签:select查询   col   ESS   none   方法   加载   action   proxy   alt   

原文地址:https://www.cnblogs.com/ltfxy/p/10313664.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!