hibernate 框架中加载方式 get 和 load 以及 慢加载 和 急加载 的区别

在hibernate中我们知道如果要从数据库中得到一个对象,通常有两种方式,一种是通过session.get()方法,另一种就是通过session.load()方法,然后其实这两种方法在获得一个实体对象时是有区别的,在查询性能上两者是不同的。

一.load加载方式

当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来加载这个对象,即:当我们使用session.load()方法来加载一个对象时,此时并不会发出sql语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的id值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出sql语句,从数据库中去查询我们的对象。

    public UserEntity findById(int uId) throws Exception {
        Session session=HibernateSessionFactory.getSession();
        //get 和    load的区别load可以找缓存,而get不会
        UserEntity user=(UserEntity) session.load(UserEntity.class, uId);
        HibernateSessionFactory.closeSession();
        return user;
    }

调用查询结果时

public class Test {
	public static void main(String[] args) {
      
     IUserDao dso=new UserDaoImpl();

      UserEntity user2=dso.findById(2);
      System.out.println(user2.getUserName());

{

控制台会报错:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
    at com.project.entity.UserEntity_$$_jvst43d_1.getUserName(UserEntity_$$_jvst43d_1.java)
    at com.project.test.Test.main(Test.java:43)

主要原因是因为:

UserEntity user=(UserEntity) session.load(UserEntity.class, uId);是从缓存中获取数据,当要获取对象的属性时才执行sql语句,
但这个时候 HibernateSessionFactory.closeSession();session已关闭就无法完成查询语句,所有会报这个错could not initialize proxy - no Session
解决方式:HibernateSessionFactory.closeSession();等所有的操作完成后再关闭,或者用get方式来获取:UserEntity user=(UserEntity) session.get(UserEntity.class, uId);
二、get加载方式
相对于load的延迟加载方式,get就直接的多,当我们使用session.get()方法来得到一个对象时,不管我们使不使用这个对象,此时都会发出sql语句去从数据库中查询出来:

 三、懒加载 和 急加载的区别:

懒加载:FathType.LAZY   :在加载一个实体的时候,不会马上从数据库加载,即从数据库加载到内存。

急加载:FathType.EAGER:在加载一个实体时会立即从数据库中查询,与其关联的类也会被同时查询。

 在我们使用@ManyToOne等时,都会被默认为急加载。


在hibernate中,我们无论是使用懒加载还是急加载,get方法都会一次加载所有基本数据类型属性的值,而load则不同。

在我们开启了懒加载之后,load方法只会加载id属性,所有的非id属性的访问操作都不会执行。只有id属性中有实际值(其实就是你调用load方法时传的那个),

在session没有关闭的之前,如果访问除id外的其他属性才会发sql语句去查询,我们经常犯的一个错误就是在当前session关闭以后访问由load()加载的对象的非id属性,

此时Hibernate尝试通过当前session发sql查询,但发现session已经关闭,这样就会发出no session的异常 。

一般我们将FetchType.lazy 改成 EAGER ,就可以避免这个错误。

但是在我们需要查询一个表时,如果这个表有很多与其关联的表,如果使用急加载的话,在第一次加载就会很慢,如果是懒加载相对则会快一些。但是在我们又需要查询与此表相关的数据的时候,急加载就会很快,因为在第一次加载的时候,已经帮我们全部加载好了。而懒加载则会相对慢一些,因为在我门需要查询的时候,它才会帮我们去查。

所以让他们算是各有优缺点。

而我们用哪一种方法更好,则需要根据我们的具体情况去使用了

 

转载于:https://www.cnblogs.com/YGZ-321/p/7247591.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值