Hibernate Session 提供了不同的方式从数据库中获取数据。其中两个是-** Get()** 和** Load()** 。对于这些,我们也有很多重载方法,可以在不同的情况下使用。乍一看,get()
和Load()
看起来很相似,因为它们都是从数据库获取数据,但它们之间几乎没有什么区别,让我们用一个简单的例子来看看它们。
1package com.journaldev.hibernate.main;
2
3import org.hibernate.Session;
4import org.hibernate.SessionFactory;
5import org.hibernate.Transaction;
6
7import com.journaldev.hibernate.model.Employee;
8import com.journaldev.hibernate.util.HibernateUtil;
9
10public class HibernateGetVsLoad {
11
12 public static void main(String[] args) {
13
14 //Prep Work
15 SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
16 Session session = sessionFactory.openSession();
17 Transaction tx = session.beginTransaction();
18
19 //Get Example
20 Employee emp = (Employee) session.get(Employee.class, new Long(2));
21 System.out.println("Employee get called");
22 System.out.println("Employee ID= "+emp.getId());
23 System.out.println("Employee Get Details:: "+emp+"\n");
24
25 //load Example
26 Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
27 System.out.println("Employee load called");
28 System.out.println("Employee ID= "+emp1.getId());
29 System.out.println("Employee load Details:: "+emp1+"\n");
30
31 //Close resources
32 tx.commit();
33 sessionFactory.close();
34 }
35}
当我执行上面的代码时,它会产生以下输出。
1Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
2Employee get called
3Employee ID= 2
4Employee Get Details:: Id= 2, Name= David, Salary= 200.0, {Address= AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051}
5
6Employee load called
7Employee ID= 1
8Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
9Employee load Details:: Id= 1, Name= Pankaj, Salary= 100.0, {Address= AddressLine1= Albany Dr, City=San Jose, Zipcode=95129}
从输出中可以明显看出,Get()
通过从数据库或从Hibernate cache获取对象来返回对象,而Load()
只返回一个可能并不实际存在的对象的引用,它仅在您访问该对象的其他属性时才从数据库或缓存加载数据。现在,让我们尝试获取数据库中不存在的数据。
1//Get Example
2try{
3Employee emp = (Employee) session.get(Employee.class, new Long(200));
4System.out.println("Employee get called");
5if(emp != null){
6System.out.println("Employee GET ID= "+emp.getId());
7System.out.println("Employee Get Details:: "+emp+"\n");
8}
9}catch(Exception e){
10 e.printStackTrace();
11}
12
13//load Example
14try{
15Employee emp1 = (Employee) session.load(Employee.class, new Long(100));
16System.out.println("Employee load called");
17System.out.println("Employee LOAD ID= "+emp1.getId());
18System.out.println("Employee load Details:: "+emp1+"\n");
19}catch(Exception e){
20 e.printStackTrace();
21}
上面的代码产生以下输出。
1Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
2Employee get called
3Employee load called
4Employee LOAD ID= 100
5Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
6org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.journaldev.hibernate.model.Employee#100]
7 at org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:253)
8 at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:262)
9 at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176)
10 at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
11 at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
12 at com.journaldev.hibernate.model.Employee_$$_jvst407_1.toString(Employee_$$_jvst407_1.java)
13 at java.lang.String.valueOf(String.java:2847)
14 at java.lang.StringBuilder.append(StringBuilder.java:128)
15 at com.journaldev.hibernate.main.HibernateExample.main(HibernateExample.java:36)
仔细观察输出,当我们使用get()
检索不存在的数据时,它返回NULL 。这是有意义的,因为它试图在被调用时立即加载数据。使用Load()
,我们可以打印id,但只要我们尝试访问其他字段,它就会触发数据库查询,如果没有找到具有给定标识符的记录,则抛出org.hibernate.ObjectNotFoundException
。它是Hibernate特有的Runtime Exception,所以我们不需要显式地捕获它。让我们也来看看一些重载方法。上面的** get()和Load()** 方法也可以编写如下。
1Employee emp = (Employee) session.get("com.journaldev.hibernate.model.Employee", new Long(2));
2
3Employee emp1 = (Employee) session.load("com.journaldev.hibernate.model.Employee", new Long(1));
4
5Employee emp2 = new Employee();
6session.load(emp1, new Long(1));
还有其他带有`LockOptions‘参数的方法,但我还没有使用过它们。请注意,我们需要将完整的类名作为参数传递。基于以上解释,我们在Get()和Load() 之间有以下区别:
1.Get()
一被调用就加载数据,而Load()
返回代理对象,只在实际需要时加载数据,所以Load()
更好,因为它支持延迟加载。
2.由于Load()
在找不到数据时会抛出异常,所以我们应该在知道有数据的情况下才使用它。
3.当我们想要确保数据库中有数据时,应该使用get()
。
这就是Hibernate的Get和Load方法,我希望它将消除一些疑虑,并帮助您决定在不同的场景中使用哪种方法。