FetchType的区别是什么。LAZY和FetchType。Java持久性API中的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;
    }
    //...
}

其他回答

如果你在使用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:它惰性地获取子实体,即在获取父实体时,它只是获取子实体的代理(由cglib或任何其他实用程序创建),当你访问子实体的任何属性时,它实际上是由hibernate获取的。

EAGER:它与父实体一起获取子实体。

为了更好地理解,请参阅Jboss文档,或者使用hibernate。Show_sql =true,检查hibernate发出的查询。

JOIN很重要

轻松地看待它:

假设我们有一个叫User的类和另一个叫Address的类,假设每个用户都有一个或多个地址,意思是关系(一对多),如果执行:

FetchType。LAZY执行sql命令,就像没有join一样:

SELECT * FROM users 

FetchType。执行sql命令:

SELECT * FROM users u join address a on a.user_id = u.user_id

注意:以上查询只是为您澄清图像,但Hibernate框架实际执行的查询与上述查询类似。

哪种获取类型更好?

由于Eager抓取会自动加载所有关系,这是一个很大的性能消耗 除非被告知,否则惰性抓取不会加载任何关系,这将带来更好的性能 即时抓取使得编程更容易,因为需要的代码更少 如果整个系统没有经过适当的测试,延迟加载可能会导致错误(异常) 考虑到所有因素,您仍然应该更喜欢Lazy加载而不是Eager加载,因为它的性能更好

如果你正在使用Spring引导框架,那么就进入应用程序。属性文件并添加下面的命令以了解到底发生了什么。

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

来自Javadoc:

EAGER策略是持久性提供程序运行时的一个要求,即必须急切地获取数据。LAZY策略是对持久性提供程序运行时的一个提示,即在第一次访问数据时应该以惰性方式获取数据。

例如,渴望比懒惰更主动。Lazy只发生在第一次使用时(如果提供者接受了暗示),而对于急切的东西(可能)会被预取。

FetchType。LAZY和FetchType。EAGER用于定义默认的读取计划。

不幸的是,您只能覆盖LAZY抓取的默认抓取计划。EAGER抓取不太灵活,可能导致许多性能问题。

我的建议是克制将关联设置为EAGER的冲动,因为取回是查询时的责任。因此,您的所有查询都应该使用fetch指令来只检索当前业务用例所需的内容。