hibernate会话的get()和load()方法在获取方面有什么区别?

时间:2014-03-03 09:27:35

标签: java hibernate

get()和load()方法有什么区别?关于数据获取方法

 public static void main(String[] args) {
    SessionFactory factory= new Configuration().configure().buildSessionFactory();
     Session session = factory.openSession();
     Transaction tx = null;
      tx = session.beginTransaction();
       System.out.println("1 st time calling load method");
        Account acc = 
               (Account)session.load(Account.class, 180); 
             System.out.println("bal"+acc.getBalance());

          System.out.println("2nd   time calling load method");
          Account  acc1=(Account)session.load(Account.class, 180); 
           System.out.println("bal"+acc1.getBalance());


        System.out.println("1 st time calling get method");
     Account acc2= (Account) session.get(Account.class, accId);

      System.out.println("bal"+acc2.getBalance());    

      System.out.println("2 st time calling get method");

     Account  acc2= (Account) session.get(Account.class, accId);

    System.out.println("bal"+acc2.getBalance());


     tx.commit();

   session.close(); 

}

我得到了以下输出

1 st time calling load method
Hibernate: 
/* load com.abcd.Account */ select
    account0_.ACCOUNTID as ACCOUNTID1_0_,
    account0_.ACCOUNTTYPE as ACCOUNTT2_1_0_,
    account0_.CREATIONDATE as CREATION3_1_0_,
    account0_.BALANCE as BALANCE1_0_ 
from
    a.MYACCOUNT account0_ 
where
    account0_.ACCOUNTID=?
bal3000.0
2nd   time calling load method
bal3000.0
1 st time calling get method
bal3000.0
2 st time calling get method
bal3000.0

从ouput中可以看出get方法没有命中数据库。它的行为与load()方法类似。任何人都可以告诉我这种行为是否正确。

11 个答案:

答案 0 :(得分:5)

正如T Mishra所说:here

  
      
  1. 默认情况下,hibernate会创建运行时代理。它将对象作为代理加载,除非指定了获取模式或设置为false。

  2.   
  3. 这是因为一旦对象加载到缓存中,下一个后续调用就会执行可重复读取。

  4.   
  5. 虽然此对象的状态从持久变为分离
  6.         

    可以通过两种方式检索实体。

         

    load() - 返回带有标识符的代理对象。

         

    get() - 从数据库中返回完整的对象。

         

    有关详细信息,请点击此link

答案 1 :(得分:3)

实际上,这两个函数都用于检索具有不同机制的对象,

  1. session.load()

    它将始终返回“代理”(Hibernate术语)而不会访问数据库。在Hibernate中,proxy是一个具有给定标识符值的对象,它的属性尚未初始化,它看起来就像一个临时假对象。 如果找不到行,则会抛出ObjectNotFoundException。

  2. session.get()

    它总是命中数据库并返回真实对象,一个表示数据库行的对象,而不是代理。 如果找不到行,则返回null。

答案 2 :(得分:2)

当你调用session.load()方法时,它总会返回一个“代理”对象,它是什么意思的代理对象? 代理意味着,hibernate将在内存中准备一些具有给定标识符值的虚假对象而不会访问数据库,例如,如果我们调用session.load(Student.class,new Integer(107)); > hibernate会在id为107的内存中创建一个伪Student对象[row],但是Student类的剩余属性甚至都不会被初始化。 enter image description here

GET

当你调用session.get()方法时,它会立即命中数据库并返回原始对象。 如果该行在数据库中不可用,则返回null。

答案 3 :(得分:1)

hibernatesession.get()将从数据库中获取真实对象,而hibernatesession.load()将返回代理而不会访问数据库。有关详细信息,请单击here。它解释了get和load方法及其与示例代码的区别。

答案 4 :(得分:1)

**加载:**每当调用 load() 方法时,hibernate会创建一个POJO类的代理对象,并将id设置为代理对象,然后它将代理对象返回给程序。基于对代理对象执行的操作,hibernate将决定是否去缓存或数据库来加载数据。此过程称为延迟加载。

**获取:**当我们调用 get() 方法时,hibernate首先进入第一级缓存,如果该对象不存在于第一级缓存然后它进入数据库并从数据库加载对象。如果数据库中不存在Id,则get()方法返回null。当调用get()方法时,不会创建任何代理对象,因此它被称为早期加载。

参考:http://docs.jboss.org/hibernate/orm/4.3/javadocs/

完整示例您可以找到@ my blog:http://www.onlinetutorialspoint.com/hibernate/hibernate-session-differences-between-load-and-get.html

答案 5 :(得分:1)

使用加载:

  • 如果您确定要检索的对象可用性 来自DB。否则,您将最终捕获ObjectNotFoundException。

  • 当您要装载重物时(因为无论何时使用它都会懒散地加载)

使用get:

  • 如果您不确定数据库中的对象可用性。
  • 如果DB中没有可用的对象,您可以检查是否为null。
  • 当你有轻物体要加载时(因为它急切地加载)。

答案 6 :(得分:0)

以下是您需要的简单说明: http://www.mkyong.com/hibernate/different-between-session-get-and-session-load/

或者通过查看API: http://docs.jboss.org/hibernate/orm/4.3/javadocs/

with get:返回给定命名实体的持久化实例。持久化的,所以存储在数据库中的那个。

with load:将与给定标识符关联的持久状态读取到给定的瞬态实例中。

在第一个链接中,您可以找到测试差异的非常有用的示例..

答案 7 :(得分:0)

加载:当我们调用session.load()方法时,它不会直接命中数据库。如果对象不属于db,它会创建并返回代理对象,它会抛出" ObjectNotFountException"。并支持延迟加载。

获取:它直接命中db中的对象,如果找不到对象则给出原始值,然后返回null。它支持急切加载。

答案 8 :(得分:0)

从上面的例子中 - 两个函数都不相同。

load() - hibernate只会加载具有指定ID的对象的代理。所有属性都不会在高级中设置。一旦在对象上调用getter方法,查询就会出现问题。 因此,当您可以使用getAccount方法时,将发出select查询,并且结果对象将在ID检索时保存在缓存中。所以通过get的任何后续调用都不会导致任何select语句。

get() - 将始终从填充了完整属性的数据库中检索对象。对于集合中定义的属性,取决于延迟初始化配置。 请注意 - 同一会话中的任何后续调用都将仅从缓存中返回对象,因此不会返回任何查询。这就是第一次调用get方法时所发生的事情,第二次调用对象在缓存中就绪,通过调用load检索的对象上的acc.getBalance()来实现。

答案 9 :(得分:0)

不要忘记get和load方法之间的性能方面

get()方法在执行时会立即获取数据,而load()方法返回代理对象,并在需要对象属性时仅提取数据。 这样load()方法可以获得更好的性能,因为它支持延迟加载。 只有当我们知道数据存在时才应该使用load()方法,因为它在未找到数据时抛出异常。

您可以在教程Difference between get and load method in Hibernate

上看到演示此差异的示例

答案 10 :(得分:0)

调用session.load()方法时,它将始终返回proxy对象,代理对象的含义是什么? Proxy意味着,休眠将在不访问数据库的情况下在内存中准备一些具有给定标识符值的假对象,例如,如果我们调用的话。

 session.load(Student.class,new Integer(107)); 
  

hibernate将在ID为107的内存中创建一个伪造的Student对象[row],但是Student类的其余属性甚至都不会初始化,请观察此图形表示…

仅当我们尝试检索Student对象的其他属性(即stdNamestdCountry)时,它才会访问数据库。
如果我们调用s2.getStdName(),那么休眠将进入数据库并搜索学生ID为107的行并检索值,如果在数据库中找不到object [row],它将抛出ObjectNotFoundException


 session.get()

调用session.get()方法时,它将立即访问数据库并返回原始对象。 如果该行在数据库中不可用,则返回null


因此,休眠load()get()是哪种最佳方法? 完全由您选择。