Общий шаблон DAO в Hibernate
Работая над hibernate, мы следуем общему шаблону Hibernate DAO, как также упоминалось в Hibernate Doc.
В соответствии с этим в настоящее время мы поддерживаем две параллельные иерархии 1) для интерфейсов 2) для реализации
поэтому, если мы будем работать над этим способом, даже если не будет предложено нового метода, кроме стандартных методов постоянства, нам нужно будет создать интерфейс маркера для этого объекта, а также для его имплиментации.
Хотя в этом подходе и его четком разделении нет проблем.
мой вопрос, есть ли лучший способ / альтернативный способ добиться этого
заранее спасибо
1 ответ
Умешь я покажу вам, как мы реализуем эту функциональность
Интерфейс
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.");
}
}
Теперь, например, если вам нужен репозиторий, которому нужен только метод add, вы можете использовать
public class PersonRepository extends AbstractRepository<Person, Integer> {
public void add(Person instance) {
/**
* person implmentatiuon goes here
*/
}
}
Если другой разработчик попытается получить доступ, кроме метода add, он или она получит исключение UnsupportedOperationException
Критерии - это просто маркерный интерфейс.
public interface Criteria {}
Назначение некоторых методов, определяющих параметр Class fetchingStrategy, заключается в сопоставлении экстернализованных именованных запросов. Таким образом, я избегаю кодированной строки, которая подвержена ошибкам. Этот подход используется проверкой bean-компонента JSR-303, например, для проверки групп свойств. Смотрите здесь
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.");
}
}