JPA数据懒加载LAZY和实时加载EAGER(转)
原文:https://www.cnblogs.com/MrSi/p/8081811.html
懒加载LAZY和实时加载EAGER的概念,在各种开发语言中都有广泛应用。其目的是实现关联数据的选择性加载,懒加载是在属性被引用时,才生成查询语句,抽取相关联数据。而实时加载则是执行完主查询后,不管是否被引用,立马执行后续的关联数据查询。社区里有人认为懒加载这种功能比较鸡肋,这种事仁者见仁,智者见智啦,个人觉得依自己业务场景而定。
顺带说一句,使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数据的。在Spring Data JPA中如何自己控制session的生命周期,这个功能我还没有研究,作为下一次的研究课题。
在今天解析懒加载与实时加载的实例时,需要借助实体关系映射功能,配置实体间的一对多(OneToMany)和多对一(ManyToOne)关系。当然,还有OneToOne、ManyToMany关系,这个如有兴趣大家就自己研究下了。
一、为实体类ProcessBlock和Node添加一对多的关联关系。在我这个示例中ProcessBlock是流程定义类,一个流程定义对应多个流程节点,即Node表。下面给出代码。
1、ProcessBlock实体定义
@Entity(name = "nbpm_processblock")
@NamedQuery(name = "ProcessBlock.findByName", query = "select p from nbpm_processblock p where p.name=?1")
public class ProcessBlock implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
long id;
@Column(name = "name")
String name;
@Column(name = "description")
String description;
@OneToMany(mappedBy="processblock",cascade=CascadeType.ALL,fetch = FetchType.EAGER)
Set<Node> nodeSet = new HashSet<Node>();
public long getId() {
return id;
}
……
定义Set<Node>属性 nodeSet,为其添加注解@OneToMany,意思就是一个ProcessBlock实体对应多个Node节点。注解属性 mappedBy,是指关联关系可以从Node类中的processblock属性上获取;cascade属性设置成CascadeType.ALL,是说主从表全面建立级联关系;fetch属性设置成FetchType.EAGER,是指加载规则是即时加载。查看源码会发现默认情况下,OneToMany注解的fetch属性设置的是FetchType.LAZY。
2、Node实体定义
@Entity(name = "nbpm_node")
public class Node implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
long id;
@Column(name = "name")
String name;
@Column(name = "description")
String description;
@Column(name = "subclass")
String subclass;
/**
* 关联关系必须存在
*/
@ManyToOne(optional = true)
@JoinColumn(name="processblock")
ProcessBlock processblock;
public long getId() {
return id;
}
……
定义ProcessBlock属性 processblock,为其添加注解@ManyToOne,意思就是一个Node实体对应一个ProcessBlock流程定义。添加注解@JoinColumn,属性name设置成"processblock",意思是nbpm_node表中的processblock字段是外键,与ProcessBlock的主键建议关联关系。需要说明一下 ManyToOne注解的fetch属性 默认是FetchType.EAGER,查询时会立马抽取对应的主表数据。这块的考虑还是很细致的,大致就是关联数据是集合时就懒加载,是单条数据时就实时加载。
二、编写查询示例并展示结果。查询使用自定义的JpaUtil工具,工具实现请参考《自定义JpaUtil,快速完成Hql执行逻辑(一)》
1、查询ProcessBlock,主干流程数据,因为设置的nodeSet属性是实时加载加载,查询完成,断点查看确实拿到了流程对应的所有节点信息。
Map<String, Object> params = new HashMap<>();
params.put("name", "主干流程");
List<ProcessBlock> list = ApplicationContextUtil.instance.getJpaUtil().list(
"select u from simm.spring.entity.ProcessBlock u where u.name=:name", params, ProcessBlock.class); Set<Node> nodes = list.get(0).getNodeSet();
-- Hibernate框架生成的查询语句 -----------------
Hibernate: select processblo0_.id as id1_2_, processblo0_.description as descript2_2_, processblo0_.name as name3_2_ from nbpm_processblock processblo0_ where processblo0_.name=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_,
nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_
from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_,
nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_
from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_,
nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_
from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_,
nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_
from nbpm_node nodeset0_ where nodeset0_.processblock=?
2、将ProcessBlock类的属性nodeSet设置成懒加载LAZY,查询后,发现对应的节点列表信息获取不到了。这里懒加载的数据读取不到是因为主查询的session已经结束。
@OneToMany(mappedBy="processblock",cascade=CascadeType.ALL,fetch = FetchType.LAZY)
//@JoinColumn(name="processblock_id")
Set<Node> nodeSet = new HashSet<Node>();
-- Hibernate框架生成的查询语句 -----------------
Hibernate: select processblo0_.id as id1_2_, processblo0_.description as descript2_2_, processblo0_.name as name3_2_ from nbpm_processblock processblo0_ where processblo0_.name=?
3、Hql直接查询关联属性
List<Node> nodeList = ApplicationContextUtil.instance.getJpaUtil().list(
"select u.nodeSet from simm.spring.entity.ProcessBlock u where u.id=1", null, Node.class);
-- Hibernate框架生成的查询语句 -----------------
Hibernate: select nodeset1_.id as id1_1_, nodeset1_.description as descript2_1_, nodeset1_.name as name3_1_, nodeset1_.processblock as processb5_1_, nodeset1_.subclass as subclass4_1_
nbpm_processblock processblo0_ inner join nbpm_node nodeset1_ on processblo0_.id=nodeset1_.processblock where processblo0_.id=1
Hibernate: select processblo0_.id as id1_2_0_, processblo0_.description as descript2_2_0_, processblo0_.name as name3_2_0_
from nbpm_processblock processblo0_ where processblo0_.id=?
JPA数据懒加载LAZY和实时加载EAGER(转)的更多相关文章
- JPA数据懒加载LAZY和实时加载EAGER(二)
懒加载LAZY和实时加载EAGER的概念,在各种开发语言中都有广泛应用.其目的是实现关联数据的选择性加载,懒加载是在属性被引用时,才生成查询语句,抽取相关联数据.而实时加载则是执行完主查询后,不管是否 ...
- JPA数据懒加载LAZY配合事务@Transactional使用(三)
上篇博文<JPA数据懒加载LAZY和实时加载EAGER(二)>讲到,如果使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数 ...
- JPA的懒加载
JPA数据懒加载LAZY和实时加载EAGER(二) 懒加载LAZY和实时加载EAGER的概念,在各种开发语言中都有广泛应用.其目的是实现关联数据的选择性加载,懒加载是在属性被引用时,才生成查询语句 ...
- DevExpress的GridControl的实时加载数据解决方案(取代分页)
http://blog.csdn.net/educast/article/details/4769457 evExpress是一套第三方控件 其中有类似DataGridView的控件 今天把针对Dev ...
- Swift - 懒加载(lazy initialization)
Swift中是存在和OC一样的懒加载机制的,在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间 懒加载 格式: lazy var 变量: 类型 = { 创建变量代码 }() 懒 ...
- Swift 懒加载(lazy) 和 Objective-C 懒加载的区别
在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间,比如iOS开发中的最常用控件UITableView,实现数据源方法的时候,通常我们都会这样写 Objective-C - ( ...
- iOS 开发——实用技术Swift篇&Swift 懒加载(lazy)
Swift 懒加载(lazy) 在程序设计中,我们经常会使用 * 懒加载 * ,顾名思义,就是用到的时候再开辟空间,比如iOS开发中的最常用控件UITableView,实现数据源方法的时候,通常我们都 ...
- Swift中懒加载(lazy initialization)的实现
Swift中是存在和OC一样的懒加载机制的,但是这方面国内的资料比较少,今天把搜索引擎换成了Bing后发现用Bing查英文\最新资料要比百度强上不少. 我们在OC中一般是这样实现懒加载初始化的: 1: ...
- js图片实时加载
浏览大型网站,特别是图片比较多的图片,如大型的电商网站,你会发现处了第一屏外,往下滚动的时候图片才加载出来,没必要一开始加载就要把全部图片加载出来,这样子打开网面的速度得到了很好提高.以下是笔者目前所 ...
随机推荐
- 数据库的 ACID 属性
ACID(Atomicity 原子性.Consistency 一致性.Isolation 隔离性.Durability 持久性)是一系列属性. 这些属性保证了数据库事物的可靠.在数据库中,对数据的一系 ...
- 机器学习入门-贝叶斯统计语料库的词频.groupby() collections
1..groupby()[].agg(by={}) 2. collections.de...(lambda:1) 统计的单词是语料库中所有的词, 对Dataframe统计单词词频,同时增加一列数据co ...
- Mybatis知识(4)
1.当实体类中的属性名和表中的字段名不一样 解决办法①: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致 <select id=”selectorder” para ...
- 【干货】国外程序员整理的 C++ 资源大全(转)
转zi:http://www.csdn.net/article/2014-10-24/2822269-c++ 关于 C++ 框架.库和资源的一些汇总列表,由 fffaraz发起和维护. 内容包括:标准 ...
- tnsping 命令解析
C:\Users\nowhill>tnsping jljcz Oracle Net 工具(命令)tnsping,是一个OSI会话层的工具,它用来: 1)验证名字解析(name resolutio ...
- SSM总结
1 报错: cvc-complex-type.2.4.a: Invalid content was found starting with element 'async-supported'. ...
- Windows7 64bit+python3.6环境下安装OpenCV3.3
安装opencv3.3 打开windows的Python扩展包网址 根据自己的系统选择下载,这里我选择的是 通过pip3安装该whl文件,使用如下命令 pip3 install 该whl的绝对路径 ...
- 启动startUML的时候报错“"Exception EOleSysError in module StarUML.exe at 000AD559. "
win7操作系统在安装startuml的时候总是报错 出现了如下错误提示:"Exception EOleSysError in module StarUML.exe at 000AD559. ...
- ArcGIS模型构建器案例学习笔记-字段处理模型集
ArcGIS模型构建器案例学习笔记-字段处理模型集 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 由四个子模型组成 子模型1:判断字段是否存在 方法:python工 ...
- Bioconductor的历史
---------------------------------------------------------------Bioconductor------------------------- ...