我有一个包含3个表的数据库。主表格为Contract
,并且它与两个表格的成对密钥相关联:Languages
和Regions
。
每一对都是唯一的,但一个合约可能会有以下一对ID:
{ (1,1), (1,2), (2,1), (2,2) }
今天,这三个表通过名为ContractLanguages
的连接实体进行链接。它包含一个序列ID,以及三个表中的三元组ID。
但是,在足够大的合同中,这会导致严重的性能问题,因为hibernate环境会创建大量的对象。
因此,我们希望删除此连接实体,以便Contract收集这些对的一些集合。
我们提出的解决方案:创建一个包含语言和地区ID的@embeddable
类,并将它们存储在Contract实体中。
这背后的想法是,语言和地区的数量相对较少。
我们假设hibernate管理这样的对的列表并且不创建重复,因此大大减少了创建的对象的数量。
但是,我们有以下问题:
答案 0 :(得分:0)
从您的帖子和评论中我假设以下情况,如果我错了,请纠正我:
Languages
+ Regions
组合(目前建模为ContractLanguages
个实体)Contract
个实体Languages
和Regions
基于这些假设,我想到了几种可能的优化:
您可以创建一个具有唯一ID的LanguageRegion
实体,每个合同都会引用一组。这样你就可以获得一个表,但是Hibernate只会为每个LanguageRegion
创建一个实体,并且每个会话加载一次,即使多个合同会引用它。为了使其正常工作,您应该使用延迟加载,并在加载合同之前将这些LanguageRegion
实体加载到第一级缓存中。
或者,您可以只加载所需的列,即只加载实体的部分。您也会使用延迟加载,但不会直接访问合同语言,而是在单独的查询中加载它们,例如(名字猜到了)
SELECT c.id, lang.id, lang.name, region.id, region.name FROM Contract c
JOIN c.contractlangues cl
JOIN cl.language lang
JOIN cl.region region
WHERE c.id in (:contractIds)
然后加载合同,获取它们的ID,使用该查询加载语言和区域详细信息(它返回一个List<Object[]>
,其中包含所选列值的对象数组。将它们放入适当的数据结构中并根据需要访问它们。这样您就可以绕过实体创建并获取所需的数据。