zoukankan      html  css  js  c++  java
  • Hibernate【性能部分】

     

    一。延迟加载。

    为什么要使用延迟加载?

      

      对于需要数据的时候才加载这种方式,就是一种优化方式

    Hibernate中的三种懒加载

    (一)类的懒加载

       

        @Test
        public void testClass_Lazy(){
            SessionFactory sessionFactory=SessionFactoryUtils.getSessionFactory();
            Session session=sessionFactory.openSession();
            Privilege privilege=(Privilege)session.load(Privilege.class, 1); //没有发出sql语句
            privilege.getName();//真正加载属性的时候发出sql语句
            session.close();
        }

      

      看到此时的privilege对象是一个代理对象(javassist我们导入过这个jar包,知道该包是创立代理对象的。代理对象最后返回了一个Privilege类型对象,可知代理对象是目标类(Privilege类)的子类)

      结论:session.load(..)产生的是代理对象,该代理类是持久化类的子类。

    (二)。集合的懒加载

        @Test
        public void testClass_Lazy2(){
            SessionFactory sessionFactory=SessionFactoryUtils.getSessionFactory();
            Session session=sessionFactory.openSession();
            Privilege privilege=(Privilege)session.get(Privilege.class, 2);
            Set<Person> persons=privilege.getPersons();
            for(Person p:persons){
                System.out.println(p.getName());
            }
            session.close();
        }

      说明:

        1.因为延迟加载在映射文件中,而映射文件一旦确定不能修改了

        2.延迟加载是通过 控制sql语句的发出时间来提高效率的

    (三)。many-to-one(单端关联)的懒加载

       根据多的一端加载一的一端

      ps:为什么不详解这种多的一方加载一的一方呢?

       根据性能来说,没有什么影响,因为只有一条数据,所以怎么样都行


    二。抓取策略

    为什么需要用到抓取策略?

      问题:在查询一对多的关联关系对象时,如何查询效率最高!(Classes -> Student)

        方法一:查询Classes的记录数,然后根据查询出来数据再去Student找到相应的数据,依据(c.id=s.cid).所以造成了N+1条查询语句。N:classes的记录数 1:classes本身

        方法二:使用iterator().来查询也会造成N+1条查询语句

        方式三:修改抓取策略,查询只需要1+1条查询语句

      总结:抓取策略解决的问题的是,如何加载Set集合中数据的问题,发出怎样的sql语句,取加载载set集合的数据。

    使用抓取策略

      因为抓取策略解决的是Set集合中数据的问题,所以在映射文件的set元素中,可以设置抓取策略,具体为

      第一步:设置映射文件中fetch属性

    <set name="persons" cascade="save-update" fetch="join">
    ....
    </set>

      fetch属性的值:

         join:左外连接:利用一条连接查询(一对多关系)两张表里的数据(ps:如果有子查询就不能用join了,此时就变成了select

        (默认)select:先查询一的一方的所有对象,再根据每一个对象的id值查询关联对象

        subselect:支持子查询  

      

      第二步:依旧采取上面方法一与方法二的查询方法,观察后台发出的sql语句

    Hibernate: 

        select

            students0_.cID as cID0_1_,

            students0_.ID as ID1_,

            students0_.ID as ID1_0_,

            students0_.NAME as NAME1_0_ 

        from

            STUDENT students0_ 

        where

            students0_.cID in (

                select

                    classes0_.ID 

                from

                    CLASSES classes0_

            )

          这样的子查询就提高了效率

    说明:

      1.因为抓取策略设置在映射文件中,所以一旦映射文件生成就不能修改了

      2.通过发出怎么样的sql语句加载集合,从而提高效率

    Hibernate支持三种查询:
    1.HQL语句

    2.条件(criteria)查询

      类的拼接,查看hibernate源文档

    3.sql查询

  • 相关阅读:
    自定义Python枚举
    解决Django跨域访问的问题
    BBS项目细节总结
    面向对象进阶
    面向对象
    三级菜单
    常用模块
    内置函数与匿名函数及递归
    迭代器和生成器
    函数
  • 原文地址:https://www.cnblogs.com/xingdongpai/p/5106343.html
Copyright © 2011-2022 走看看