3.4.6. 实体以及查询语句缓存
- 实体缓存
-
实体缓存由 EclipseLink ORM 框架提供。它将内存中最近读取或写入的实体实例存储,从而最大限度地减少数据库访问并提高应用程序性能
实体缓存仅在根据 ID 检索实体时使用,因此根据其它属性的查询仍在数据库上执行。但是,如果相关实体位于缓存中,则这些查询可以更简单、更快速。例如,如果查询与客户相关的订单并且不使用缓存,则 SQL 查询将包含客户表的 JOIN 关联。如果客户实体被缓存,则 SQL 查询将仅选择订单,并且将从缓存中检索相关客户。
要启用实体缓存,请在 core 模块的 app.properties 文件中设置以下属性:
-
eclipselink.cache.shared.sales$Customer = true
- 启用sales$Customer
实体的缓存。 -
eclipselink.cache.size.sales$Customer = 500
- 将sales$Customer
的缓存大小设置为 500 个实例。默认大小为 100。如果启用了实体缓存,则始终建议增加缓存大小的值。否则,如果查询返回的记录数超过 100,则将对查询结果的每条记录执行大量的获取操作。
实体是否被缓存会影响平台选择的用于加载实体关系图的获取模式。如果引用属性是可缓存的实体,则获取模式始终为
UNDEFINED
,这允许 ORM 从缓存中检索引用,而不是使用 JOIN 执行查询或单独的批量查询。平台在中间件集群中提供实体缓存协调机制。在一个群集节点上更新或删除缓存实体时,其它节点(如果有)上的相同缓存实例将失效,因此使用此实例的下一个操作将从数据库中读取新状态。
-
- 查询缓存
-
查询缓存存储由 JPQL 查询返回的实体实例的标识符,因此它很自然地补充了实体缓存机制。
例如,如果为实体启用了实体缓存(例如,
sales$Customer
),并且首次执行查询语句select c from sales$Customer c where c.grade = :grade
,则会发生以下情况:-
ORM 在数据库上运行查询。
-
已加载的
Customer
实例放置在实体缓存中。 -
查询文本和返回实例的标识符列表参数的映射被放到查询缓存中。
当第二次使用相同的参数执行相同的查询时,平台会在查询缓存中查找查询结果,并通过标识符从实体缓存中加载实体实例。不需要数据库操作。
默认情况下不缓存查询。可以指定应用程序的不同层缓存查询:
-
使用 EntityManager 时,使用 Query 接口的
setCacheable()
方法。 -
使用DataManager时,使用
LoadContext.Query
接口的setCacheable()
方法。 -
使用datasources时,使用
CollectionDatasource
接口的setCacheable()
方法或cacheable
XML 属性
仅在为返回的实体启用实体缓存时才使用可缓存查询。否则,每个查询实体实例将通过其标识符逐个从数据库中获取。
app-core.cuba:type=QueryCacheSupport
JMX-bean 可用于监视缓存状态并手动释放缓存的查询。例如,如果已直接在数据库中修改了sales$Customer
实体的实例,则应使用带有sales$Customer
参数的evict()
操作释放该实体的所有缓存的查询。以下应用程序属性会影响查询缓存:
-