代码之家  ›  专栏  ›  技术社区  ›  ptomli

用hibernate实现基于集合的(ddd)存储库

  •  1
  • ptomli  · 技术社区  · 16 年前

    我想看看是否可以将存储库实现为 java.util.Collection (很可能是 Map )

    大致如下:

    @Repository
    public abstract class HibernateRepository<K extends Serializable, V>
        extends AbstractMap<K, V> {
    
        @Autowired
        private SessionFactory sessionFactory;
    
        private Class<K> keyClass;
        private Class<V> valueClass;
    
        public HibernateRepository(Class<K> keyClass, Class<V> valueClass) {
            this.keyClass = keyClass;
            this.valueClass = valueClass;
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public V get(Object key) {
            return (V) sessionFactory.getCurrentSession()
                                     .get(valueClass, (Serializable) key);
        }
    
        @Override
        @Transactional
        public Set<java.util.Map.Entry<K, V>> entrySet() {
            return new EntrySet(sessionFactory.getCurrentSession());
        }
    
        private class EntrySet extends AbstractSet<java.util.Map.Entry<K, V>> {
    
            private Session session;
    
            public EntrySet(Session session) {
                this.session = session;
            }
    
            @Override
            public Iterator<java.util.Map.Entry<K, V>> iterator() {
                // Hibernate Criteria doesn't do Iterator
                // so would probably a fair bit of manual work
                // if multiple DB requests are to be avoided
            }
            @Override
            public int size() {
                return (Integer) session.createCriteria(valueClass)
                                        .setProjection(Projections.rowCount())
                                        .uniqueResult();
            }
        }
    }
    
    public class FooRepository extends HibernateRepository<Integer, Foo> {
        public FooRepository() { super(Integer.class, Foo.class); }
    
        // domain specific queries/methods...
        public Foo findMagicOne(....) { ... }
    }
    

    显而易见的问题是

    • 尽量避免向数据库提出愚蠢的请求
    • 同步化

    在我的域模型中,很多时候将db视为list/map/set是有用的,因此尝试使用标准java.util接口来实现这一点似乎是明智的。

    有这样的例子吗?我是不是要趴在地上,去做像推 Comparable.compareTo 通过Hibernate操作到数据库?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Edward Q. Bridges    16 年前

    在hibernate中,存储库的大致等价物是 DAO . 您可以看看这个模式以及它们是如何在那个链接上实现它的;您可以将其演变成类似于存储库的东西。

    在许多n层体系结构中,事务语义是在与dao不同的层上处理的。因此,您可能需要重新考虑该部分,或找到将它们集成到存储库中的方法。

    为了避免不必要或重复的交互,您可以考虑使用二级缓存。