Hibernate中get方法和load方法的区别

1.从返回结果上对比:

load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常;

get方法检索不到的话会返回null;

2.从检索执行机制上对比:

load方法的执行则比较复杂首先查找session的persistent Context(一级缓存)中是否有缓存,如果有则直接返回,如果没有则去查找二级缓存,如果有则返回,如果没有则判断是否是lazy,若不是lazy,直接访问数据库检索,查到记录返回(并且同时在二级缓存中存放查到的数据方便下次使用,若再下次使用时在二级缓存命中,就是查到数据,则有可能将数据放到

一级缓存中。),查不到抛出异常。 若是lazy,则返回代理对象,而不到数据库中查找,除非使用此对象时,才到数据库中查找。

get方法先到一级缓存,然后二级,最后db查找。

 

Get加载(数据库中存在检索的数据)

public void testLoadNotNull() {  
        Session session= HibernateUtils.getSession();  
        
        // 数据库中存在id为2的数据  
        User user = (User)session.load(User.class, 2);
    
        System.out.println(user);  
        System.out.println(user.getId() + "---->>" + 
         user.getName());  

        HibernateUtils.closeSession();  
    
}

      因为Hibernate规定get方法不能使用延迟加载,当执行到User user = (User)session.get(User.class, 2);这条语句时,get方法首先会查询session缓存,没有的话就查询二级缓存,最后会查询数据库,因此在执行该语句的时候,会先发出sql语句进行查询。而且,执行get方法的时候,get方法每次都会从数据库直接查询。

Get加载(数据库中不存在检索的数据)

/** 
 * 查询数据库中不存在的数据 
 */  
public void testGetWithNull() {  

         Session session  = HibernateUtils.getSession();  

       User user = (User)session.get(User.class, 0);
        System.out.println(user);  
        HibernateUtils.closeSession();  
   
}

 同上,在执行到User user = (User)session.get(User.class, 0);这条语句时,get方法每次都是直接查询数据库,在执行该语句时,Hibernate会发出sql语句,到数据库进行查询数据,由于id为0的数据不存在,get方法查询不到数据时,会返回null。

 

Load加载(数据库中存在检索的数据)

/** 
 * 数据库中存在查询的数据 
 */  
public void testLoadNotNull() {  
  
        Session session = HibernateUtils.getSession();  

       User user = (User)session.load(User.class, 2);</span>  
       
        System.out.println(user);  
       
        user.getName());  
       
        HibernateUtils.closeSession(session);  
    }  
}
  Hibernate中,load方法是支持懒加载的,在执行到User user = (User)session.load(User.class, 2);这条语句时,load方法首先会查找session的persistent Context中是否存在缓存,如果存在则直接返回;如果没有缓存,则load方法会判断是否是lazy加载,如果不是lazy方式,则直接访问数据库,查询Id为2的数据,由于数据库中存在Id为2的数据,因此get方法会返回实体对象。
 在这个例子中,load方法采用的是lazy方式,因此在执行load方法时,Hibernate不会发出sql语句,因为此时Hibernate建立了代理对象,但并没有访问代理对象的属性。当执行System.out.println(user);时,Hibernate才会初次发出sql语句,
 

Load加载(数据库中不存在检索的数据)

/** 
 * 数据库中不存在查询的数据 
 */  
public void testLoadWithNull() {  
        Session session = HibernateUtils.getSession();  
       User user = (User)session.load(User.class, 0);
        System.out.println(user);  
        user.getName());  
        HibernateUtils.closeSession(session);  
    
}

 

    在执行到load方法时,load方法会首先查询session中是否存在缓存,如果存在则直接返回,如果不存在则会判断是否为lazy,这里设置的是lazy方式,因此load方法会认为数据库     中存在数据,直接建立代理对象,把代理对象返回给user。
    而执行到System.out.println(user);时,Hibernate会发出sql语句,访问数据库查询Id为0的数据,由于数据库中不存在Id为0的数据,因此load方法会返回org.hibernate.ObjectNotFoundException,直接抛出异常。
 
总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。
posted @ 2017-07-27 23:38  玛旁雍错  阅读(5548)  评论(0编辑  收藏  举报