FetchType的区别是什么。LAZY和FetchType。Java持久性API中的EAGER ?
当前回答
基本上,
LAZY = fetch when needed
EAGER = fetch immediately
其他回答
有一个小小的评论: 如果你使用惰性类型,如果你关闭会话,你以后将不能从数据库中获取数据(参见下面的输出)。
但是对于Eager类型,你在获取Instructor的同时获取数据,所以在session.close()之后,你将能够使用/显示这些课程列表数据。
@OneToMany(//fetch = FetchType.EAGER,
fetch = FetchType.LAZY,
mappedBy = "instructor",
cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH})
private List<Course> courseList;
我建议在调试模式下尝试这两种方法。在这种情况下,我使用惰性类型,你可以看到。
try {
//start the transaction
session.beginTransaction();
//Get instructor from database
int instructorId = 7;
Instructor tempInstructor = session.get(Instructor.class,instructorId);
System.out.println("Instructor: "+tempInstructor);
//commit transaction
session.getTransaction().commit();
//close session
session.close();
//since courselist is lazy loaded... this should fail
//so in here we are not able to fetch courselist data
//get courses
System.out.println("Courses "+tempInstructor.getCourseList() );
System.out.println("Done!");
} finally {
session.close();
factory.close();
}
}
输出异常:
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.exercise.hibernate.entity.Instructor.courseList, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:621)
at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
at java.base/java.lang.StringConcatHelper.simpleConcat(StringConcatHelper.java:408)
at com.exercise.hibernate.main.EagerLazyLoading.main(EagerLazyLoading.java:56)
要理解它们之间的区别,最好的方法是了解lazy-okay。 FetchType。LAZY告诉hibernate在使用关系时只从数据库中获取相关的实体。
p.s.:在我参与过的许多项目中,我看到许多软件开发人员并不重视他们,甚至有人称自己为高级开发人员。如果您正在进行的项目不是在大量数据上进行数据交换,那么在这里使用EAGER是可以的。但是,考虑到可能出现n+1个问题的问题,您需要在默认情况下知道关系的获取类型之后注意这些问题。
这里你可以看到默认值: Hibernate中的默认获取类型为一对一、多对一和一对多
而且,即使在理解了取回类型之后,它也不会就此结束。要理解何时使用LAZY和何时使用EAGER,还需要理解单向和双向的概念。此外,spring引导存储库有一些方法允许它为懒惰或急切的用户读取数据。例如,getOne()或getById()方法允许您从实体中延迟获取数据。简而言之,你用什么,什么时候用,取决于对方想让你做什么。
FetchType。LAZY和FetchType。EAGER用于定义默认的读取计划。
不幸的是,您只能覆盖LAZY抓取的默认抓取计划。EAGER抓取不太灵活,可能导致许多性能问题。
我的建议是克制将关联设置为EAGER的冲动,因为取回是查询时的责任。因此,您的所有查询都应该使用fetch指令来只检索当前业务用例所需的内容。
Hibernate默认选择Lazy Fetch类型,除非显式地标记Eager Fetch类型。为了更准确和简洁,差异可以表述如下。
FetchType。LAZY =它不会加载关系,除非你通过getter方法调用它。
FetchType。EAGER =加载所有的关系。
这两种取回类型的优缺点。
延迟初始化通过避免不必要的计算和减少内存需求来提高性能。
主动初始化占用内存较多,处理速度较慢。
话虽如此,这两个初始化中的任何一个都可以使用,这取决于具体情况。
来自Javadoc:
EAGER策略是持久性提供程序运行时的一个要求,即必须急切地获取数据。LAZY策略是对持久性提供程序运行时的一个提示,即在第一次访问数据时应该以惰性方式获取数据。
例如,渴望比懒惰更主动。Lazy只发生在第一次使用时(如果提供者接受了暗示),而对于急切的东西(可能)会被预取。
推荐文章
- 一对多、多对一、多对多的区别?
- 从枚举中选择一个随机值?
- 如何从URL获取参数与JSP
- 如何在Eclipse中生成Javadoc注释?
- 找到java类从哪里加载
- 从集合中随机选取一个元素
- 为什么x == (x = y)和(x = y) == x不一样?
- 什么Java 8流。收集等价物可在标准Kotlin库?
- 等待未来的名单
- 如何检查JSON键是否存在?
- 为什么MongoDB Java驱动在条件中使用随机数生成器?
- 即使从未抛出异常,使用try-catch块的代价是否昂贵?
- 什么时候我们应该使用观察者和可观察对象?
- Java中的split()方法对点(.)不起作用。
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?