hibernate懒加载原理

当使用session中的load方法查询数据库中的记录时,我们返回的是一个代理对象,而不是真正需要的那个对象;例如数据库中存有个Student表,我们有cn.binyulan.doman.Student的领域对象,如果查询Id值为“200626313”的Student stu = (Student)session.load(Student.class,"200626313"),然后我们打印System.out.println(stu.getClass);得到的结果为cn.binyulan.domain.Student$$EnhancerByCGLIB$$5a7cc325,名字很奇怪吧,这个对象是Hibernate帮我们生成的,从名字可以看出它是对Student类的增强类的对象,其实这就是个代理对象,这个对象里并没有我们需要的Student的数据,所以如果你在session关闭后在使用stu来获取信息,如stu.getName();就会出现如下异常:org.hibernate.LazyInitializationException: could not initialize proxy - no Session,这就说明了stu中没有我们需要的数据了。


      stu对象现在到底是什么呢,它其实是一个代理类,这个类具有查询数据库的能力,当session没有关闭的时候如果我们调用stu.getName()方法;那么这个类会去查询数据库并返回相应的数据。之后我们关闭session之后再去使用这个类就不会有异常了,可是我们如果调用stu.getName()只是为了让代理类去查数据库,如果别人看我们的代码时候觉得这两句在逻辑上根本就没有用,别人就很容易注释掉,一注释掉就又会出现异常了,所以hibernate提供了一个方法Hibernate.initialize(stu);这样就可以初始化这个代理对象了。


       不知道大家注意到没有,上面的那句代码Student stu = (Student)session.load(Student.class,"200626313")把stu强制转化为Student类型,有人会问:不是返回的是代理对象么,那怎么又强制转换成Student了呢,其实代理类是Student的子类,它具有了比父类更强的能力(数据库查询),这个类是怎么生成的呢?其实hibernate使用了asm.jar和cglig-2.1.3.jar,在内存中修改Student类的字节码,修改后的字节码只要符合class文件的规则,就可以创建出代理对象。


       Domain对象不应该final的,大家现在应该明白为什么了吧,如果是final的,那么就不可以继承,当然也就不可以产生代理对象,也就不能实现懒加载了,如果你不用懒加载,那么把domain对象设计成fianl的也是可以的


Load()方法的懒加载原理

在Hibernate中,查询方法有两个,分别是get()和load(),这两种方法的不同就是load()拥有懒加载的特性。Load()方法就是在查询某一条数据的时候并不会直接将这条数据以指定对象的形式来返回,而是在你真正需要使用该对象里面的一些属性的时候才会去数据库访问并得到数据。他的好处就是可以减少程序本身因为与数据库频繁的交互造成的处理速度缓慢。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值