Hibernate3.6.2 懒加载分析

原文链接:http://xdwangiflytek.iteye.com/blog/1830969

懒加载是指程序推迟访问数据库,这样做可以保证有时候不必要的访问数据库,提供性能。

一、load方法的懒加载  

Java代码   收藏代码
  1. public class UserManager {   
  2.         public static void main(String[] args) {   
  3.             Users user = new Users();   
  4.             user.setBirthday(new Date());   
  5.             Name name = new Name();   
  6.             name.setFirstName("wang");   
  7.             name.setLastName("xudong");   
  8.                   
  9.             user.setName(name);   
  10.             addUser(user);   
  11.               
  12.             Users users = getUser(user.getId());   
  13.             System.out.println(users.getName());   
  14.               
  15.         }   
  16.       
  17.         static Users getUser(int id){   
  18.             Session session = HibernateUtil.getSession();   
  19.             try {   
  20.                 Users users = (Users) session.load(Users.class, id);   
  21.                 return users;   
  22.             } finally{   
  23.                 session.close();   
  24.             }   
  25.         }   
  26.           
  27.         static void addUser(Users users){   
  28.             Session session = null;   
  29.             Transaction tx = null;   
  30.               
  31.             try {   
  32.                 session = HibernateUtil.getSession();   
  33.                 tx = session.beginTransaction();   
  34.                       
  35.                 session.save(users);   
  36.                 tx.commit();   
  37.             } catch (HibernateException e) {   
  38.                 if (tx!=null) {   
  39.                 tx.rollback();   
  40.             } throw e;   
  41.             }finally{   
  42.                 if(session!=null){   
  43.                 session.close();   
  44.             }   
  45.         }   
  46.     }  

上面代码是先增加一个用户、然后再查询这个用户的name组合属性。运行上面的时候,该程序会抛出这样一个异常:Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session这就是懒加载不能初始化异常。其原因就在于no session。在前面个持久化对象中已经说明:使用load方法时,该方法将具有延迟加载的功能,load方法并不会立即去访问数据库,它会返回一个代理对象,只有当你真正去访问这个对象的时候,它才会去访问数据库。

 

通过上面的图,我们看出,Hibernate根本就没有select语句,也就是说Hibernate没有去访问数据库,所以这个时候你去访问它肯定是没有的。但为什么没有抛出空指针异常?没有抛出空指针异常,也就是说明User对象是存在的,那它是什么呢?通过输出user.getClass()可以看出是这样一个东西:class com.hibernate.domain.Users_$$_javassist_5。这个user就是load返回的代理对象。但是这个对象并不是我们所要的。我们所要的是一个User实例对象。

 

那么怎么解决这个问题呢?

 

第一种方法:在关闭session之前访问该对象

Java代码   收藏代码
  1. static Users getUser(int id){   
  2.  Session session = HibernateUtil.getSession();   
  3.  try {   
  4.      Users users = (Users) session.load(Users.class, id);   
  5.      users.getName();   
  6.      return users;   
  7.  } finally{   
  8.      session.close();   
  9.  }   
  10. }  

 

但是从规范性上看,别不符合规范,所以我们一般也可以采用

Java代码   收藏代码
  1. static Users getUser(int id){   
  2.     Session session = HibernateUtil.getSession();   
  3.     try {   
  4.         Users users = (Users) session.load(Users.class, id);   
  5.         Hibernate.initialize(users);   
  6.         return users;   
  7.     } finally{   
  8.         session.close();   
  9.     }   
  10. }  

 利用hibernate的initialize()方法将这个代理对象给初始化。

注:在使用代理对象的getId()方法和getClass()方法的时候,并不会抛出不能初始化异常,因为这两个属性并不用查询数据库。

 

 

二、关联关系下的懒加载

 1one-to-one懒加载

 一对一的懒加载并不常用,因为懒加载的目的是为了减少与数据库的交互,从而提高执行效率,而在一对一关系中,主表中的每一条数据只对应从表的一条数据库,就算都查询也不会增加多少交互的成本,而且主表不能有contrained=true,所以主表是不能懒加载的。但是从表可以有。

 实现此种懒加载必须在从对象这边同时满足三个条件:

 1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)

 2、Constrained = true ;

 3、fetch=select。

 注:当fetch设置为join时,懒加载就会失效。因为fetch的作用是抓取方式,他有两个值分别为select和join,默认值为select。即在设为join时,他会直接将从表信息以join方式查询到而不是再次使用select查询,这样导致了懒加载的失效。

 

2one-to-many懒加载

 与one-to-one关联不同,对one-to-many而言,主表的每一条属性都会对应从表的多条数据,这个时候懒加载就显得非常有效了。比如一个部门里面有多个员工,如果没有懒加载,每查询这个部门的时候都会查询出多个员工,这会大大增加与数据库交互的成本。所以Hbernate默认的是加入懒加载的。这就是查询集合属性的时候返回的是一个PersistentIndexed*类型对象的原因。该对象其实就是一个代理对象。当然,可以在映射文件中通过将lazy属性设为假来禁用。

Hibernate默认对one-to-many就是使用的懒加载,但用户也可以取消懒加载操作:

一:设置lazy=”false”;

二:设置fetch=”join”.

实现此种懒加载必须在从对象这边同时满足两个条件:

1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)

2、fetch=select。

 

3many-to-one懒加载

此关联关系的懒加载和one-to-one的懒加载一样都是可要可不要的,因为对执行效率的提高都不是非常明显。虽然多对一与一对一关系方式相同,但是在Hibernate中多对一时,默认是进行懒加载的。另外有一点需要注意的是懒加载并不会区分集合属性里面是否有值,即使是没有值,他依然会使用懒加载。

实现此种懒加载必须在从对象这边同时满足两个条件

1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)

2、fetch=select

 

4many-to-many懒加载

此关联关系的懒加载和one-to-many的懒加载一样对程序的执行效率的提高都是非常明显的。

实现此种懒加载必须在从对象这边同时满足两个条件:

1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)

2、fetch=select

能够懒加载的对象都是被改过的代理对象,当相应的对象没有关闭时,访问这些懒加载对象的属性(getId和getClass除外)Hibernate会初始化这些代理,或用hibernate.initalize(proxy)来初始化代理对象;当关闭session后在访问懒加载的对象就会出现异常


内容概要:本文详细探讨了双馈风力发电机(DFIG)在Simulink环境下的建模方法及其在不同风速条件下的电流与电压波形特征。首先介绍了DFIG的基本原理,即定子直接接入电网,转子通过双向变流器连接电网的特点。接着阐述了Simulink模型的具体搭建步骤,包括风力机模型、传动系统模型、DFIG本体模型和变流器模型的建立。文中强调了变流器控制算法的重要性,特别是在应对风速变化时,通过实时调整转子侧的电压和电流,确保电流和电压波形的良好特性。此外,文章还讨论了模型中的关键技术和挑战,如转子电流环控制策略、低电压穿越性能、直流母线电压脉动等问题,并提供了具体的解决方案和技术细节。最终,通过对故障工况的仿真测试,验证了所建模型的有效性和优越性。 适用人群:从事风力发电研究的技术人员、高校相关专业师生、对电力电子控制系统感兴趣的工程技术人员。 使用场景及目标:适用于希望深入了解DFIG工作原理、掌握Simulink建模技能的研究人员;旨在帮助读者理解DFIG在不同风速条件下的动态响应机制,为优化风力发电系统的控制策略提供理论依据和技术支持。 其他说明:文章不仅提供了详细的理论解释,还附有大量Matlab/Simulink代码片段,便于读者进行实践操作。同时,针对一些常见问题给出了实用的调试技巧,有助于提高仿真的准确性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值