hibernate框架检索策略之get与load

来源:互联网 发布:混也是一种生活 知乎 编辑:程序博客网 时间:2024/06/06 02:17

这篇文章只讨论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.NullPointerExceptionat 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












0 0
原创粉丝点击