这篇文章只讨论get和load,因此所有可以设置lazy的地方都不设置,即不考虑lazy的影响(lazy的作用是在查询N的时候要不要把1也查出来)
先说一下get和load的区别,下面再通过例子来演示
1.get方法采用立即加载的方式(会立即向数据库发送查询语句),而load方法采用延迟加载的方式(返回的是一个代理对象,此代理对象只有一个id,只有等真正使用该对象属性的时候,才会发送查询语句)
2.如果数据库没有对应的记录,get方法返回的是null,而load方法返回的是objectnotfoundexception
我的数据库里保存了一个student表,表里有一条id为4028e3e65a598b90015a598b92730000的记录
Student std = session.load(Student.class, "4028e3e65a598b90015a598b92730000");
System.out.println(std.getClass());
System.out.println(std.getId());
//System.out.println(std.getName());
看上面这个例子,我们用的load延迟加载的方式查询数据库中的记录,并且输出了对象和id。
你觉得会发送查询语句吗?有人会想,先打印的是代理对象应该不会发,再打印的是id,用到了该对象的属性应该就发了。
答案是不会发,你觉得用到了id,应该发送sql语句,你把id给了session,它已经知道id了,不用去数据库查也知道啊,所以是不会发的。
只有当你要打印,除了id之外的元素,他才会发sql语句的,比如被注释掉的name。
下面我们到数据库查询一条不存在的记录,把id改为"无"
Session session = sessionFactory.openSession();
Student std = session.load(Student.class, "无");
//System.out.println(std.getClass());
//System.out.println(std.getId());
System.out.println(std.getName());
再看一下打印的内容吧
Hibernate:
select
student0_.ID as ID1_1_0_,
student0_.NAME as NAME2_1_0_,
student0_.banji_id as banji_id3_1_0_
from
STUDENT student0_
where
student0_.ID=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [tm.change.domain.Student#无]
at org.hibernate.boot.internal.StandardEntityNotFoundDelegate.handleEntityNotFound(StandardEntityNotFoundDelegate.java:28)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:236)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:158)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:260)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:68)
at tm.change.domain.Student_$$_jvstb38_1.getName(Student_$$_jvstb38_1.java)
at tm.change.test.Test.queryTest(Test.java:33)
因为我们用到了name,所以它要发送sql到数据库查找,最终没有找到,报了objectnotfoundexception
再试一下get方法用id为"无"来查找吧
Hibernate:
select
student0_.ID as ID1_1_0_,
student0_.NAME as NAME2_1_0_,
student0_.banji_id as banji_id3_1_0_
from
STUDENT student0_
where
student0_.ID=?
java.lang.NullPointerException
at tm.change.test.Test.queryTest(Test.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
因为get为立即加载,所以发送了sql。最终没有找到,报了nullpointerexception