老师你好 我又来了,关于session懒加载
来源:7-4 服务器联系人和关注人接口实现-2

weixin_慕尼黑8068974
2020-04-12
老师 能给简单讲解一下关于session懒加载的原理吗?
这是您的源码:
/**
* 关注人的操作
*
* @param origin 发起者
* @param target 被关注的人
* @param alias 备注名
* @return 被关注的人的信息
*/
public static User follow(final User origin, final User target, final String alias) {
UserFollow follow = getUserFollow(origin, target);
if (follow != null) {
// 已关注,直接返回
return follow.getTarget();
}
return Hib.query(session -> {
// 想要操作懒加载的数据,需要重新load一次
session.load(origin, origin.getId());
session.load(target, target.getId());
// 我关注人的时候,同时他也关注我,
// 所有需要添加两条UserFollow数据
UserFollow originFollow = new UserFollow();
originFollow.setOrigin(origin);
originFollow.setTarget(target);
// 备注是我对他的备注,他对我默认没有备注
originFollow.setAlias(alias);
// 发起者是他,我是被关注的人的记录
UserFollow targetFollow = new UserFollow();
targetFollow.setOrigin(target);
targetFollow.setTarget(origin);
// 保存数据库
session.save(originFollow);
session.save(targetFollow);
return target;
});
}
问题一:你说在操作懒加载数据的时候要进行load,那么 下面targetFollow.setOrigin(target)和targetFollow.setTarget(origin) 里面里面是用到懒加载数据了吗?所以必须要重新加载一次?在网上查到的都是关于load与get的不同,说是get直接发送查询语句而load是用到内部数据才会延迟发送语句,否则load返回的是代理对象,但似乎和这里感觉不太一样,能给说说吗?
问题二:最后返回target时 你提到target是被加载过的所以可以直接返回,意思是target是内部有懒加载数据的吧?这里是不是与session的生命周期有关了?当对象被load后你说就会和session绑定到一起了,是不是就是这个意思,在session关闭之前,所有被load的对象里面的懒加载数据都会被实时更新呢?是这样理解吗?
我的理解是:
session.load(obj,obj.getId());是指的 将obj里面的懒加载数据进行加载,然后再赋值到原来这个obj中,这样obj就是全数据的对象了。
在整个session生命周期中,对数据库进行操作,操作到关于懒加载数据时,obj里面的懒加载数据也会跟着发生变化。
1回答
-
我直接全局说一下吧。
对于一个类中有设置懒加载的字段时,那么第一次查询的数据将不包含懒加载的字段数据。并且当前累会被代理返回。
如果在当前session周期内有使用到懒加载字段,这会触发代理对象的查询自动返回。
此时与没有使用懒加载的操作基本类似。
但是,如果退出当前session周期后其代理对象绑定的session就断开了,此时如果再访问没有加载过的懒加载字段将触发异常。
所以我们需要重新开启一个session,并调用load将当前实例传递进去,此时会再次将代理对象和session绑定起来。
然后就可以正常使用懒加载字段了。
132020-05-29
相似问题