在处理hibernate时,我们遵循Hibernate Doc中提到的泛型Hibernate DAO模式。
因此,我们目前正在维持两个平行的hirarchies 1)用于接口 2)对于Implimentation
所以,如果我们按照标准持久性方法除了提出新方法之外的方法,我们需要为该实体创建一个标记界面以及它的Implimentation。
虽然这种方法似乎没有问题,但是它的分离是明确的。
我的问题是,是否有更好的方式/替代方式来实现这个
提前致谢
答案 0 :(得分:8)
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 {}
某些方法的目的是定义参数类fetchingStrategy 是为了匹配外部化的命名查询。这样,我避免了易于出错的手工编码字符串。例如,JSR-303 bean验证使用此方法来验证属性的组。见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.");
}
}