FetchType的区别是什么。LAZY和FetchType。Java持久性API中的EAGER ?
当前回答
有时你有两个实体它们之间有关系。例如,你可能有一个实体叫University,另一个实体叫Student,一个University可能有很多Student:
University实体可能有一些基本属性,如id、名称、地址等,以及一个名为students的集合属性,它返回给定大学的学生列表:
public class University {
private String id;
private String name;
private String address;
private List<Student> students;
// setters and getters
}
现在,当您从数据库加载University时,JPA将为您加载它的id、名称和地址字段。但是你有两种选择:
将它与其他字段一起加载(即急切地加载),或者 在调用大学的getStudents()方法时按需加载它(即惰性加载)。
当一所大学有很多学生时,加载所有的学生并不是有效的,特别是当他们不需要的时候,在这种情况下,你可以声明你想要在实际需要学生的时候加载他们。这被称为惰性加载。
下面是一个例子,学生被明确地标记为急切加载:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.EAGER)
private List<Student> students;
// etc.
}
这里有一个例子,学生被明确地标记为惰性加载:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.LAZY)
private List<Student> students;
// etc.
}
其他回答
Hibernate默认选择Lazy Fetch类型,除非显式地标记Eager Fetch类型。为了更准确和简洁,差异可以表述如下。
FetchType。LAZY =它不会加载关系,除非你通过getter方法调用它。
FetchType。EAGER =加载所有的关系。
这两种取回类型的优缺点。
延迟初始化通过避免不必要的计算和减少内存需求来提高性能。
主动初始化占用内存较多,处理速度较慢。
话虽如此,这两个初始化中的任何一个都可以使用,这取决于具体情况。
如果你在使用Hibernate,你可以在调用getStudents()方法时调用Hibernate.initialize():
Public class UniversityDaoImpl extends GenericDaoHibernate<University, Integer> implements UniversityDao {
//...
@Override
public University get(final Integer id) {
Query query = getQuery("from University u where idUniversity=:id").setParameter("id", id).setMaxResults(1).setFetchSize(1);
University university = (University) query.uniqueResult();
***Hibernate.initialize(university.getStudents());***
return university;
}
//...
}
基本上,
LAZY = fetch when needed
EAGER = fetch immediately
FetchType。LAZY和FetchType。EAGER用于定义默认的读取计划。
不幸的是,您只能覆盖LAZY抓取的默认抓取计划。EAGER抓取不太灵活,可能导致许多性能问题。
我的建议是克制将关联设置为EAGER的冲动,因为取回是查询时的责任。因此,您的所有查询都应该使用fetch指令来只检索当前业务用例所需的内容。
来自Javadoc:
EAGER策略是持久性提供程序运行时的一个要求,即必须急切地获取数据。LAZY策略是对持久性提供程序运行时的一个提示,即在第一次访问数据时应该以惰性方式获取数据。
例如,渴望比懒惰更主动。Lazy只发生在第一次使用时(如果提供者接受了暗示),而对于急切的东西(可能)会被预取。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 原则-如何打印出真正的sql,而不仅仅是准备好的语句?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder