如何缓存hibernate集合?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何缓存hibernate集合?相关的知识,希望对你有一定的参考价值。
我有两个实体com.gn.entities.Report和com.gn.entities.ReportSummary。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD z.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.gn.entities.Report" table="REPORT" >
<id name="id" type="int" column="id" >
<generator class="native"/>
</id>
<property name="name">
<column name="NAME" />
</property>
<set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >
<key column="RPT_ID" not-null="true"></key>
<one-to-many class="com.gn.entities.ReportSummary"/>
</set>
</class>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.gn.entities.ReportSummary" table="REPORT_SUMMARY" >
<composite-id name="id" class="com.gn.entities.ReportSummaryId">
<key-property name="id" column="ID"></key-property>
<key-many-to-one name="report" class="com.gn.entities.Report" column="RPT_ID"/>
</composite-id>
<property name="name">
<column name="NAME" />
</property>
</class>
我想知道它们之间有什么区别
场景1:实体和集合上的缓存标记
<class name="com.gn.entities.Report" table="REPORT" >
<cache usage="read-write" region="report"/>
和
<set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >
<cache usage="read-write" region="report"/>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.gn.entities.Report" table="REPORT" >
<cache usage="read-write" region="report"/>
<id name="id" type="int" column="id" >
<generator class="native"/>
</id>
<property name="name">
<column name="NAME" />
</property>
<set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >
<cache usage="read-write" region="report"/>
<key column="RPT_ID" not-null="true"></key>
<one-to-many class="com.gn.entities.ReportSummary"/>
</set>
</class>
和
方案2:仅在实体上的缓存标记(<cache usage="read-write" region="report"/>
)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.gn.entities.Report" table="REPORT" >
<cache usage="read-write" region="report"/>
<id name="id" type="int" column="id" >
<generator class="native"/>
</id>
<property name="name">
<column name="NAME" />
</property>
<set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >
<!-- <cache usage="read-write" region="report"/> -->
<key column="RPT_ID" not-null="true"></key>
<one-to-many class="com.gn.entities.ReportSummary"/>
</set>
</class>
问题1:在两种情况下,Report和ReportSummary都将被缓存?如果是,那么使实体和集合可以缓存的用途是什么?
问题2:此外,是否提取影响缓存(fetch = join或fetch = select)?在两种情况下?
<set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >
and
<set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="select" >
更新: -
好的,这意味着我必须使ReportSummary也可以缓存。完成后我发现我仍然收到如下日志消息: -
17:23:04,824 TRACE DefaultLoadEventListener:403 - 尝试解决:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}]
17:23:04,824 TRACE DefaultLoadEventListener:427 - 对象未在任何缓存中解析:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}]
17:23:04,824 TRACE AbstractEntityPersister:3923 - 获取实体:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}] 17:23: 04,824 DEBUG Loader:2105 - 正在加载实体:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}] 17:23:04,824 DEBUG SQL: 104 - / * load com.gn.entities.ReportSummary / select reportsumm0_.ID as ID1_1_0_,reportsumm0_.RPT_ID as RPT2_1_0_,reportsumm0_.NAME as NAME3_1_0_ from REPORT_SUMMARY reportsumm0_ where reportsumm0_.ID =?和reportsumm0_.RPT_ID =? Hibernate:/ load com.gn.entities.ReportSummary * / select reportsumm0_.ID as ID1_1_0_,reportsumm0_.RPT_ID as RPT2_1_0_,reportsumm0_.NAME as NAME3_1_0_ from REPORT_SUMMARY reportsumm0_ where reportsumm0_.ID =?和reportsumm0_.RPT_ID =?
17:23:04,824 TRACE JdbcCoordinatorImpl:319 - 注册语句[com.mysql.jdbc.JDBC4PreparedStatement@e3c0e40:/ * load com.gn.entities.ReportSummary * / select reportsumm0_.ID as ID1_1_0_,reportsumm0_.RPT_ID as RPT2_1_0_,reportsumm0_。名称为NAME3_1_0_,来自REPORT_SUMMARY reportsumm0_,其中reportsumm0_.ID = **未指定**和reportsumm0_.RPT_ID = **未指定] 17:23:04,824 TRACE JdbcCoordinatorImpl:329 - 注册最后一个查询语句[com.mysql.jdbc.JDBC4PreparedStatement @ e3c0e40:/ * load com.gn.entities.ReportSummary * / select reportsumm0_.ID as ID1_1_0_,reportsumm0_.RPT_ID as RPT2_1_0_,reportsumm0_.NAME as NAME3_1_0_ from REPORT_SUMMARY reportsumm0_ where reportsumm0_.ID = NOT SPECIFIED **和reportsumm0_.RPT_ID = * * 未标明 **]
这意味着hibernate找到了ReportSummary id,它将命中数据库以使用该id获取ReportSummary实体?
那么,如果有10000个ReportSummary实体,那么将有10000个数据库命中?
在任何一种情况下都不会缓存ReportSummary
实例,因为您没有将该实体类标记为可缓存。
如果Report
实体被声明为可缓存,那么显然Hibernate会将其实例缓存在二级缓存中。
如果reportSummaryList
不可缓存,则无论Report
是否可缓存,都不会缓存该集合。
如果reportSummaryList
是可缓存的,那么Hibernate会缓存ReportSummary
中存在的reportSummaryList
实例的id。 ReportSummary
是否可缓存无关紧要; ids缓存在单独的缓存条目中。但是,在这种情况下,您可能还希望使ReportSummary
实体可缓存,以便在根据缓存集合条目中包含的ID读取其实例时提高性能。
以上是关于如何缓存hibernate集合?的主要内容,如果未能解决你的问题,请参考以下文章
[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓