一尘不染

Hibernate中的通用DAO模式

hibernate

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

因此,据此,我们目前为接口2)维护两个并行的层次结构1)以实现

因此,即使我们在标准持久性方法之外没有提出任何新方法的情况下以这种方式进行工作,我们也需要为该对象及其实现创建标记界面。

尽管这种方法及其明确的分隔似乎没有问题。

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

提前致谢


阅读 372

收藏
2020-06-20

共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
          */    
    }

}

如果其他开发人员尝试访问除添加方法以外的其他方法,则他或她将获得 UnsupportedOperationException

条件 只是标记界面

public interface Criteria {}

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

public class Person {
    public static interface PERSON_WITH_ADDRESS {}
}

外部化命名查询如下所示

<?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.");
    }

}
2020-06-20