【问题标题】:Generic DAO pattern in HibernateHibernate 中的通用 DAO 模式
【发布时间】:2010-12-29 06:07:20
【问题描述】:

在开发 hibernate 时,我们也遵循 Hibernate Doc 中提到的通用 Hibernate DAO 模式。

因此,我们目前正在维护两个并行的层次结构 1) 用于接口 2)用于实现

因此,如果我们以这种方式工作,即使除了标准持久性方法之外没有提议的新方法,我们也需要为该条目及其实现创建一个标记接口。

虽然这种方法和明确的分离似乎没有问题。

我的问题是是否有更好的方法/替代方法来实现这一目标

提前致谢

【问题讨论】:

    标签: hibernate design-patterns jakarta-ee dao


    【解决方案1】:

    Umesh 我将向您展示我们如何实现此功能

    界面

    public interface Repository<INSTANCE_CLASS, PRIMARY_KEY_CLASS> {
    
        void add(INSTANCE_CLASS instance);
        void merge(INSTANCE_CLASS instance);
        void remove(PRIMARY_KEY_CLASS id);
        INSTANCE_CLASS findById(PRIMARY_KEY_CLASS id);
        INSTANCE_CLASS findById(PRIMARY_KEY_CLASS id, Class fetchingStrategy, Object... args);
        List<INSTANCE_CLASS> findAll();
        List<INSTANCE_CLASS> findAll(Class fetchingStrategy, Object... args);
        List<INSTANCE_CLASS> findAll(int pageNumber, int pageSize);
        List<INSTANCE_CLASS> findAll(int pageNumber, int pageSize, Class fetchingStrategy, Object... args);
        List<INSTANCE_CLASS> findAllByCriteria(Criteria criteria);
        List<INSTANCE_CLASS> findAllByCriteria(Criteria criteria, Class fetchingStrategy, Object... args);
        List<INSTANCE_CLASS> findAllByCriteria(int pageNumber, int pageSize, Criteria criteria);
        List<INSTANCE_CLASS> findAllByCriteria(int pageNumber, int pageSize, Criteria criteria, Class fetchingStrategy, Object... args);
    
    }
    

    因为您通常不需要上面显示的所有方法,所以我们创建了一个抽象类目的是作为一个虚拟实现

    public abstract class AbstractRepository<INSTANCE_CLASS, PRIMARY_KEY_CLASS> implements Repository<INSTANCE_CLASS, PRIMARY_KEY_CLASS> {
    
        public void add(INSTANCE_CLASS instance) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public void merge(INSTANCE_CLASS instance) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public void remove(PRIMARY_KEY_CLASS id) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
    
        public INSTANCE_CLASS findById(PRIMARY_KEY_CLASS id) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public INSTANCE_CLASS findById(PRIMARY_KEY_CLASS id, Class fetchingStrategy, Object... args) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAll() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAll(Class fetchingStrategy, Object... args) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAll(int pageNumber, int pageSize) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAll(int pageNumber, int pageSize, Class fetchingStrategy, Object... args) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAllByCriteria(Criteria criteria) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAllByCriteria(Criteria criteria, Class fetchingStrategy, Object... args) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAllByCriteria(int pageNumber, int pageSize, Criteria criteria) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public List<INSTANCE_CLASS> findAllByCriteria(int pageNumber, int pageSize, Criteria criteria, Class fetchingStrategy, Object... args) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
    }
    

    现在,例如,如果你想要一个只需要添加方法的存储库,你可以使用

    public class PersonRepository extends AbstractRepository<Person, Integer> {
    
        public void add(Person instance) {
            /**
              * person implmentatiuon goes here
              */    
        }
    
    }
    

    如果其他开发者尝试访问 add 方法以外的方法,他或她将得到 UnsupportedOperationException

    条件只是一个标记界面

    public interface Criteria {}
    

    一些方法定义参数Class fetchingStrategy的目的是为了匹配外部化的命名查询。这样,我避免了容易出错的手工编码字符串。例如,JSR-303 bean 验证使用这种方法来验证 groups 属性。见here

    public class Person {
        public static interface PERSON_WITH_ADDRESS {}
    }
    

    externalize命名查询如下所示

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <query name="PERSON_WITH_ADDRESS">
            <![CDATA[
                from 
                    Person p
                left join fetch 
                    p.address
            ]]>
        </query>
    </hibernate-mapping>
    

    所以当我想检索所有有地址的人时,我打电话

    PersonRepository<Person, Integer> respository ...
    
    List<Person> personList = repository.findAll(PERSON_WITH_ADDRESS.class);
    

    findAll 可以写成

    public class PersonRepository extends AbstractRepository<Person, Integer> {
    
        List<Person> findAll(Class fetchingStrategy, Object... args) {
            if(fetchingStrategy.isAssignableFrom(PERSON_WITH_ADDRESS.class)) {
                sessionFactory.getCurrentSession()
                              .getNamedQuery(fetchingStrategy.getSimpleName())
                              .list();
            }
    
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
    }
    

    【讨论】:

    • @umesh awasthi 如果我的回答满足您的需求或有用,请将其标记为已接受或给予 UPvote。谢谢!
    • 您能否解释/链接在人员类中使用标记接口而不是静态最终字符串的好处,ty
    • @umesh awasthi 如果您使用标记接口而不是普通字符串,则可以依赖 IDE 提供的重构。如果您将公共接口重命名为 PERSON_WITH_ADDRESS {},则此更改将反映在您的代码中,无论它位于何处。但是如果你使用纯字符串,你就不能安全地重构它。
    猜你喜欢
    • 1970-01-01
    • 2018-01-10
    • 2012-03-15
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多