Hibernate的性能优化——延迟加载(懒加载)

Hibernate的性能优化——延迟加载(懒加载)

通过asm和cglib两个包实现

1、  session.load()时,系统并没有直接去访问数据库,而是通过new来创建代理对象(代理对象不会为空,不能判定)。

代理对象限制:和代理关联的session关闭之前才能使用

User.getname()或user.getBirthday()和初始化的方式Hibernate.initialize(user),hibernate才会访问数据库,select语句才会输出

User.getClass()和user.getId()不会访问数据库

 public static User getUser(int id){

       Session session=null;

 

       try{

           session=HibernateUtil.getSession();

           Class clazz=User.class;

           //Useruser=(User) session.get(clazz, id);

           User user=(User) session.load(clazz,id);

           System.out.println(user.getClass());

//user.getBirthday();

           Hibernate.initialize(user);

           //---持久态

           return user;

       }finally{

           if(session!=null)

              session.close();

      

    }

2、  对象和对象之间存在关联

(1)      一对一关联关系

必须满足三个条件时才能实现懒加载

1)Lazy!=false 2)constrained=”true”  3)fetch=select

当我们查询的是主对象时,将person和idcard做了外连接,查询出person和idcard。没有懒加载。(因为主表不能有constrained=true,所以主表没有懒加载)

    static Person query(int id){

       Session s=null;

       Transaction tx=null;

       try{

           s=HibernateUtil.getSession();

           tx=s.beginTransaction();

           //查询

           IdCard idCard=null;

           Person p=(Person) s.get(Person.class,id);//查主对象没有懒加载

           tx.commit();

           return p;

       }finally{

           if(s!=null)

              s.close();

       }

    }

当查询从对象时,对于idcard所关联的person对象是懒加载的。

static IdCard query(int id){

       Session s=null;

       Transaction tx=null;

       try{

           s=HibernateUtil.getSession();

           tx=s.beginTransaction();

           //查询

           IdCard idCard=(IdCard) s.get(IdCard.class,id);

           Hibernate.initialize(idCard.getPerson());

           tx.commit();

           return idCard;

       }finally{

           if(s!=null)

              s.close();

       }

    }

(2)  一对多

1)  lazy!=false 2)fetch=select

(3)  多对一

1)  lazy!=false 2)fetch=select

(4)  多对多

1)  lazy!=false 2)fetch=select

Lazy:指相关联的属性什么时候抓取

Fetch:通过什么方式来进行抓取  select二次select语句查询 Join连接查询,lazy属性就不起作用

抓取策略

抓取策略来直接影响session的get()或load()方法的执行效率。主要有以下两种情况

1、 单端关联(<many-to-one>、<one-to-one>)上的抓取策略

可以给单端关联的映射元素添加fetch属性。Fetch属性可能有两个值

Select:作为默认值,它的策略是当需要使用到关联对象的数据时,另外单独发送一条select语句抓取当前对象的关联对象的数据。即延迟加载。

Join:它的策略是在同一条select语句使用内连接来获得对象的数据和它的关联对象的数据,此时关联对象的延迟加载失败。

2、 集合属性上的抓取策略

在集合属性的映射元素上可以添加fetch属性,它有三个可选值。

Select:作为默认值,它的策略是当需要使用所关联集合的数据时,另外单独发送一条select语句抓取当前对象的关联集合,即延迟加载。

Join:在同一条select语句使用内连接来获得对象的关联集合,此时关联集合上的lazy会失效。

Subselect:另外发送一条查询语句(或子查询语句)抓取在前面查询到的所有实体对象的关联集合。这个策略对HQL的查询也起作用。

关闭延迟加载

延迟加载确实会给程序的查询效率带来好处,但有时明确知道数据需要立即加载的,如果Hibernate先默认使用延迟加载,而后又必须去数据库加载,反而会降低效率。所以需要根据应用程序的实际情况来灵活控制是否使用延迟加载。在Hibernate中只需要修改相应的配置来启用或关闭延迟加载的功能。

1、 在加载单个实体,如果不需要延迟加载,就可以使用session的get()方法。

2、 当session加载某个实体时,不需要对这个实体中的集合属性值延迟加载,而是要立即加载。这时可以在映射文件针对这个集合的配置元素(<set>、<bag>、<list>…)添加属性lazy=false。

3、 当session加载某个实体时,不需要对这个实体所单端关联的另一个实体对象延迟加载,就可以在映射文件中针对这个单端关联的配置元素(<ont-to-one>、<many-to-one>)添加属性lazy=false。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值