Hibernate懒/急加载示例

这篇文章将重点讨论为什么以及如何在应用程序中使用称为LAZY和EAGER加载的概念,以及如何使用Spring的休眠模板以EAGER方式加载LAZY实体。

当然,正如标题本身所暗示的那样,我们将通过一个示例来说明这一点。 场景就是这样;

您是一个有很多玩具的孩子的父母。 但是当前的问题是,只要您打电话给他(我们假设您有一个男孩),他也会带着所有玩具来找您。 现在这是一个问题,因为您不希望他一直都随身携带玩具。

因此,作为理论上的父母,您会继续前进,并将孩子的玩具定义为LAZY。 现在,每当您打电话给他时,他都会不带玩具来到您身边。

但是您面临另一个问题。 当需要进行家庭旅行时,您希望他带上他的玩具,因为否则孩子会厌倦这次旅行。 但是,由于您对孩子的玩具严格执行LAZY,因此您无法要求他随身携带玩具。 这是EAGER提取起作用的地方。 首先让我们看看我们的领域类。

package com.fetchsample.example.domain;import java.util.HashSet;
import java.util.Set;import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;/*** Holds information about the child* * @author dinuka.arseculeratne* */
@Entity
@Table(name = 'CHILD')
@NamedQuery(name = 'findChildByName', query = 'select DISTINCT(chd) from Child chd left join fetch chd.toyList where chd.childName=:chdName')
public class Child {public static interface Constants {public static final String FIND_CHILD_BY_NAME_QUERY = 'findChildByName';public static final String CHILD_NAME_PARAM = 'chdName';}@Id@GeneratedValue(strategy = GenerationType.AUTO)/*** The primary key of the CHILD table*/private Long childId;@Column(name = 'CHILD_NAME')/*** The name of the child*/private String childName;@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)/*** The toys the child has. We do not want the child to have the same toy more than* once, so we have used a set here.*/private Set<Toy> toyList = new HashSet<Toy>();public Long getChildId() {return childId;}public void setChildId(Long childId) {this.childId = childId;}public String getChildName() {return childName;}public void setChildName(String childName) {this.childName = childName;}public Set<Toy> getToyList() {return toyList;}public void addToy(Toy toy) {toyList.add(toy);}}
package com.fetchsample.example.domain;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;/*** Hols data related to the toys a child possess* * @author dinuka.arseculeratne* */
@Entity
@Table(name = 'TOYS')
public class Toy {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = 'TOY_ID')/*** The primary key of the TOYS table*/private Long toyId;@Column(name = 'TOY_NAME')/*** The name of the toy*/private String toyName;public Long getToyId() {return toyId;}public void setToyId(Long toyId) {this.toyId = toyId;}public String getToyName() {return toyName;}public void setToyName(String toyName) {this.toyName = toyName;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((toyName == null) ? 0 : toyName.hashCode());return result;}@Override/*** Overriden because within the child class we use a Set to* hold all unique toys*/public boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Toy other = (Toy) obj;if (toyName == null) {if (other.toyName != null)return false;} else if (!toyName.equals(other.toyName))return false;return true;}@Overridepublic String toString() {return 'Toy [toyId=' + toyId + ', toyName=' + toyName + ']';}}

如您所见,我们有两个简单的实体分别代表孩子和玩具。 这个孩子与这些玩具有一对多的关系,这意味着一个孩子可以拥有许多玩具(哦,我多么想念我的童年时代)。 之后,我们需要与数据进行交互,因此让我们继续定义DAO(数据访问对象)接口和实现。

package com.fetchsample.example.dao;import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import com.fetchsample.example.domain.Child;/*** The basic contract for dealing with the {@link Child} entity* * @author dinuka.arseculeratne* */
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public interface ChildDAO {/*** This method will create a new instance of a child in the child table* * @param child*            the entity to be persisted*/public void persistChild(Child child);/*** Retrieves a child without his/her toys* * @param childId*            the primary key of the child table* @return the child with the ID passed in if found*/public Child getChildByIdWithoutToys(Long childId);/*** Retrieves the child with his/her toys* * @param childId*            the primary key of the child table* @return the child with the ID passed in if found*/public Child getChildByIdWithToys(Long childId);/*** Retrieves the child by the name and with his/her toys* * @param childName*            the name of the child* @return the child entity that matches the name passed in*/public Child getChildByNameWithToys(String childName);}
package com.fetchsample.example.dao.hibernate;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import com.fetchsample.example.dao.ChildDAO;
import com.fetchsample.example.domain.Child;/*** The hibernate implementation of our {@link ChildDAO} interface* * @author dinuka.arseculeratne* */
public class ChildDAOHibernateImpl extends HibernateDaoSupport implementsChildDAO {/*** {@inheritDoc}*/public void persistChild(Child child) {getHibernateTemplate().persist(child);}/*** {@inheritDoc}*/public Child getChildByIdWithoutToys(Long childId) {return getHibernateTemplate().get(Child.class, childId);}/*** {@inheritDoc}*/public Child getChildByIdWithToys(Long childId) {Child child = getChildByIdWithoutToys(childId);/*** Since by default the toys are not loaded, we call the hibernate* template's initialize method to populate the toys list of that* respective child.*/getHibernateTemplate().initialize(child.getToyList());return child;}/*** {@inheritDoc}*/public Child getChildByNameWithToys(String childName) {return (Child) getHibernateTemplate().findByNamedQueryAndNamedParam(Child.Constants.FIND_CHILD_BY_NAME_QUERY,Child.Constants.CHILD_NAME_PARAM, childName).get(0);}}

一个简单的合同。 我有四种主要方法。 当然,第一个只是将子实体持久化到数据库中。

第二种方法通过传入的主键来检索Child,但不提取玩具。

第三种方法首先获取Child,然后使用Hibernate模板的initialize()方法检索Child的玩具。 请注意,当您调用initialize()方法时,hibernate将把您LAZY定义的集合获取到您检索的Child代理中。

最终方法还可以检索“儿童”的玩具,但这一次使用命名查询。 如果返回到Child实体的Named查询,则可以看到我们使用了“ left join fetch ”。 当返回有资格的Child实体时,实际上是关键字fetch也会初始化玩具集合。 最后,我有我的主班来测试我们的功能;

package com.fetchsample.example;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.fetchsample.example.dao.ChildDAO;
import com.fetchsample.example.domain.Child;
import com.fetchsample.example.domain.Toy;/*** A test class* * @author dinuka.arseculeratne* */
public class ChildTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext('com/fetchsample/example/spring-context.xml');/*** First we initialize a child*/Child child = new Child();/*** A cool ben 10 action figure*/Toy ben10 = new Toy();ben10.setToyName('Ben 10 figure');/*** A even more cooler spider man action figure*/Toy spiderMan = new Toy();spiderMan.setToyName('Spider man figure');child.setChildName('John');/*** Add the toys to the collection*/child.addToy(ben10);child.addToy(spiderMan);ChildDAO childDAO = (ChildDAO) context.getBean('childDAO');childDAO.persistChild(child);Child childWithoutToys = childDAO.getChildByIdWithoutToys(1L);// The following line will throw a lazy initialization error since we have// defined fetch type as LAZY in the Child domain class.// System.out.println(childWithToys.getToyList().size());Child childWithToys = childDAO.getChildByIdWithToys(1L);System.out.println(childWithToys.getToyList().size());Child childByNameWithToys = childDAO.getChildByNameWithToys('John');System.out.println(childByNameWithToys.getToyList().size());}
}

将基础实体定义为LAZY是一种好习惯,因为在很多情况下,您可能不希望实体内的集合,而只想与基础实体中的数据进行交互。 但是,如果需要集合的数据,则可以使用前面提到的任何一种方法。

今天就是这样。 对于任何想尝试该示例的人,我都在这里上传了该示例。

参考: “ 我的旅程” IT博客中的JCG合作伙伴 Dinuka Arseculeratne 举例说明了使用休眠模式进行延迟/延迟加载 。


翻译自: https://www.javacodegeeks.com/2012/08/hibernate-lazyeager-loading-example.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371439.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读者使用计算机终端是指,全国2010年10月自学考试管理系统中计算机应用真题及答案...

A.上级模块向下级模块传递控制信号B.下级模块对上级模块传递控制信号C.同级模块之间传递数据或控制信号D.上级模块向下级模块传递数据信号18.“客户”数据表结构为&#xff1a;客户编号、手机号、购物金额&#xff0c;合理的字段类型为( )A.字符型&#xff0c;字符型&#xff0…

软件测试HW02-------fault error failure

程序一 问题一&#xff1a;i应该>0&#xff1b; 问题二&#xff1a; x为空 问题三&#xff1a;test x[2, 3, 5]; y 3;问题四:test: x[2]; y 3&#xff1b;程序二问题一&#xff1a;循环应该反过来;问题二&#xff1a;无;问题三&#xff1a;test:x[1];问题四:test: x[1,2,3…

Mathematica图片局部变色

这篇博客来源于Stack-Exchange上的一个帖子&#xff0c;问题描述如下&#xff1a;如何将图中的红球变为蓝球&#xff1f; 这个问题下面有很多答案&#xff0c;我选了最好的一个答案&#xff0c;代码如下 img Import["C:/Users/1/Desktop/red.jpg"]; getReds[x_Image…

在WebLogic 12c上运行RichFaces

我最初以为我可以在几个月前写这篇文章。 但是我最终被不一样的事情所淹没。 其中之一是&#xff0c;它无法像我在4.0版本中那样简单地启动RichFaces展示柜。 有了所有的JMS magic和不同的提供者检查&#xff0c;这已经成为简单构建和部署它的挑战。 无论如何&#xff0c;我愿意…

Spring Boot系列教程一:Eclipse安装spring-tool-suite插件

一.前言 一直使用eclipse&#xff0c;个人习惯选用Eclipsespring-tool-suite进行开发&#xff0c;特别注意Eclipse要选用对应的spring-tool-suite进行安装&#xff0c;这点笔者浪费了好长时间&#xff0c;以下为对应的版本。eclipse-kepler.4.3.1–>springsource-tool-suite…

湖南工程学院计算机网络考试,湖南工程学院 计算机网络期末试卷试题

湖南工程学院 计算机网络期末试卷试题湖南工程学院 计算机网络 期末试题(计算机10级&#xff0c;90%的题目)1 从逻辑功能上看,计算机网络可分为哪两个子网?答&#xff1a;通信子网和资源子网 2 数据链路层的最基本功能答&#xff1a;数据链路层的最基本的功能是向该层用户提供…

C#设计模式(11)——外观模式(Facade Pattern)

一、引言 在软件开发过程中&#xff0c;客户端程序经常会与复杂系统的内部子系统进行耦合&#xff0c;从而导致客户端程序随着子系统的变化而变化&#xff0c;然而为了将复杂系统的内部子系统与客户端之间的依赖解耦&#xff0c;从而就有了外观模式&#xff0c;也称作 ”门面“…

OS X Mountain Lion上的多个Java版本

在Mountain Lion之前&#xff0c;Java被捆绑在OS X中。似乎在升级期间&#xff0c;我在计算机上安装的Java 6版本被删除了。 显然&#xff0c;在升级过程中卸载Java的原因是Java运行时存在的安全问题。通过这种方式&#xff0c;您不得不安装可解决此安全问题的最新版本。 所以我…

Oracle锁机制的总结【转】

最近在研究Oracle锁机制的时候发现网上的资料鱼龙混杂将&#xff0c;很多将问题复杂化&#xff0c;让人感觉没有条理性。经过查询原始理论资料&#xff0c;总结如下&#xff1a; 在数据库理论中&#xff0c;我们知道。我们在执行并发访问数据库表时&#xff0c;如果没有任何一致…

2020暨阳学院园林计算机考研考场,【图片】2020考研,老学长教你如何规划!【计算机考研吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼二、关键一步——院校选择我把各位同学的院校选择阶段分为以上几个阶段&#xff0c;因为考研这一年中&#xff0c;很多人的目标院校并不是固定不变的&#xff0c;而是随着不同阶段而改变的。学长我在大三下学期这一时间段内也多次更…

List Box 控件

1 //定义变量&#xff0c;并关联控件与变量。IDC_RecvData为控件ID&#xff0c;recvData为控件对应的变量名 2 CListBox recvData; 3 4 DDX_Control(pDX, IDC_RecvData, recvData); 5 6 //向List Box控件IDC_RecvData中添加一行数据 7 CString str&#xff1b; 8 recvData.Ad…

JavaOne 2012:向上,向上和向外:使用Akka扩展软件

在最后的社区主题演讲后&#xff0c;我前往希尔顿金门大桥3/4/5观看了维克多巴生 &#xff08; Viktor Klang &#xff09;的&#xff08; Typesafe &#xff09;“上&#xff0c;下&#xff0c;外&#xff1a;Akka”演讲。 巴生&#xff08;Klang&#xff09;是Akka的技术主管…

华北科技学院计算机期末考试,华北科技学院 专业计算机 考试专用

1不能应用修剪命令“trim”进行修剪的对象是(D、文字) 。2. 命令行(B.不能随意移动)3. 布尔运算中差集的热键为(A.SU)4. 定距等分点用( C.DIST)命令5. 标高是以( B.厘米) 为单位6. 在建筑平面图中用以指明朝向的是( B.指北针)7. A3图纸的尺寸是( c.420x297)8. 既可以绘制直线&a…

redux-plain-english-workflow

https://quickleft.com/blog/redux-plain-english-workflow/转载于:https://www.cnblogs.com/skating/p/6495384.html

Spring测试支持和上下文缓存

Spring为单元测试和集成测试提供了全面的支持-通过注释来加载Spring应用程序上下文&#xff0c;并与JUnit和TestNG等单元测试框架集成。 由于为每个测试加载大型应用程序上下文需要时间&#xff0c;因此Spring智能地为测试套件缓存应用程序上下文–通常&#xff0c;当我们通过a…

perl6正则 4: before / after 代码断言: ?{} / !{}

<?before> <? befor XXX> 某字符在 xxx 之前 <?after > <?after XXX> 某字符之后有XXX 对应的取反分别为: <!before > <!before XXX> XXX之前没有 <!after> <!after xxx> 某字符后面不是 xxx say "foobar" ~~…

mac 下JDK 与 tomcat 的安装与配置

一.Mac下JDK的安装 1.先检测Mac是否已经安装过JDK&#xff0c;在终端中输入java 或者 javac 显示说明&#xff0c;表明已经安装过JDK&#xff0c;JDK版本查询终端键入java &#xff0d;version&#xff0c;终端会返回JDK的版本号。 2.如果没有安装JDK&#xff0c;登陆 http://w…

新型发明创造大赛计算机类,2017年发明杯全国高职高专大学生创新创业大赛

以“发明创新实现梦想、创意创业改变生活”主题活动为依托&#xff0c;把课内与课外教育相结合&#xff0c;学校教育、家庭教育与社会教育相结合&#xff0c;培养广大在校大学生的科技创新意识和实践动手能力&#xff0c;激发他们设计创造的乐趣&#xff0c;使广大大学生大胆创…

如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)- 续(附demo)

转载&#xff1a;http://www.cnblogs.com/codeon/p/6123863.html 上篇文章说到接口安全的设计思路&#xff0c;如果没有看到上篇博客&#xff0c;建议看完再来看这个。 通过园友们的讨论&#xff0c;以及我自己查了些资料&#xff0c;然后对接口安全做一个相对完善的总结&#…

PrimeFaces在GlassFish 3.1.2.2上推动大气

PrimeFaces 3.4在三天前问世。 除了通常令人敬畏的新组件和更新组件之外&#xff0c;它还包括新的PrimeFaces Push框架。 基于Atmosphere&#xff0c;这为您的应用程序提供了简单的推送机制。 这是在最新的GlassFish 3.1.2.2上配置和运行它的方法。 准备工作 像往常一样&#…