在Hibernate环境下对大型集合的处理
在Hibernate环境下对大型集合的处理
猪刚烈 发表于3年前
在Hibernate环境下对大型集合的处理
  • 发表于 3年前
  • 阅读 3
  • 收藏 0
  • 点赞 0
  • 评论 0

华为云·免费上云实践>>>   

在Hibernate环境下,对大型集合的访问管理是一个非常值得重视的问题。一次将大型集合加载到内存是不能容忍的。因此在操作这种集合时要特别小心。下面给出一些建议。

1.使用@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)注解大型集合,确保在访问集合的size(),isEmpty(),contains()方法时不会导致整个集合载入内存。这个方法的作用有限,如果调用add(),remove()等方法时,这个集合还是会加载出来。

2. 反向bag和list集合是性能最高的。这一点体现在使用collection.add()或collection.addAll()时也不会导致整个集合加载。(注意:必须是反向集合)。但是考虑到bag集合的种种缺点,这一点可利用的价值也不大。

3. 避免一切可能导致整个集合被一次性加载出来的操作。这需要在集合的宿主对象上屏蔽该集合的get方法,禁止外部直接获取该集合的引用。

4. 如果集合被封装到宿主对象内部,那么如果需要向集合add/remove/update元素,应该怎样处理呢?这是一个值得仔细考虑的问题。目前我倾向于这样处理:如果元素是聚合根,那么我们应该独立对它进行CRUD,宿主对象就不再提供add/remove/update方法了。如果是非聚合根,特别是值对象,对他们的CRUD往往是直接由它们的宿主对象来实现的。这时需要宿主对象提供 add/remove/update 方法,这些方法会通过domain event模式将对象直接持久化到数据库。注意:这里不存在级联的说法。任何通过java collection add/remove/update 元素的做法都会导致整个集合被加载。这是不能容许的。

 

5.对于DataAccessBasedCollection和普通集合的取舍

如果我们舍弃通过普通集合来映射多端实体,那将让我们失去hibernate提供的对这些集合处理的所有好处,比如:缓存,级联操作等等。

如果要对大型集合做映射,一定要控制对这些集合的任意访问。如果某些操作需要通过集合来完成, 比如CRUD集合中的元素,或是遍历集合找出某些特定的元素,这操作是不适宜由领域对象来完成了,即使它们可能带有一定的业务逻辑。这些操作可能会通过某些service方法来单独处理吧?

共有 人打赏支持
粉丝 22
博文 708
码字总数 110
作品 1
×
猪刚烈
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: