您的位置:首页 > 其它

在Hibernate环境下对大型集合的处理

2010-05-10 10:51 99 查看
在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方法来单独处理吧?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: