Ответ 1
Наличие одного класса реализует каждый DAO-интерфейс во всем приложении, будет довольно плохим дизайном.
Более типичным шаблоном является интерфейс BaseDAO
(также часто называемый GenericDAO
) и имеющий JPABaseDAO
, JDBCBaseDAO
и т.д. Эти базовые классы будут содержать такие методы, как find/get/read, save/сохранять/сохранять, обновлять/изменять и удалять/удалять/очищать.
Конкретные интерфейсы DAO, такие как UserDAO
, затем наследуют от BaseDAO
, а конкретные реализации, такие как JPAUserDAO
, проходят от JPABaseDAO
.
A BaseDAO
может выглядеть следующим образом:
public interface BaseDAO <T> {
T getByID(Long ID);
T save(T type);
T update(T type);
void delete(T type);
}
И интерфейс UserDAO
:
public interface UserDAO extends BaseDAO<User> {
List<User> getAllAuthorized();
}
Пример bare bones для JPABaseDAO
, реализующий этот интерфейс:
@Stateless
public class JPABaseDAO<T> implements BaseDAO<T> {
@PersistenceContext
private EntityManager entityManager;
private final Class<T> entityType;
@SuppressWarnings("unchecked")
public JPABaseDAO() {
this.entityType = ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
}
@Override
public T getByID(Long ID) {
return entityManager.find(entityType, ID);
}
@Override
public T save(T type) {
return entityManager.persist(type);
}
@Override
public T update(T type) {
return entityManager.merge(type);
}
@Override
public void delete(T type) {
entityManager.remove(entityManager.contains(type) ? type : entityManager.merge(type));
}
}
И некоторые примеры реализации UserDAO
, которые наследуют от него:
@Stateless
public class JPAUserDAO extends JPABaseDAO<User> implements UserDAO {
@PersistenceContext
private EntityManager entityManager;
@Override
public List<User> getAllAuthorized() {
return entityManager.createNamedQuery("User.getAllAuthorized", User.class)
.getResultList();
}
}
На практике базовый класс может часто делать некоторые другие вещи прозрачно, например, проверять, реализует ли какой-либо объект интерфейс Auditable
, и автоматически устанавливает дату и пользователя, которые его модифицировали, и т.д.
При использовании EJB для реализации ваших DAO одной стратегией для изменения реализаций будет включение всех реализаций JDBC в один пакет и все реализации JPA в другой. Тогда просто включите только один пакет реализации в свою сборку.