hibernate框架检索策略之get与load

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












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值