让单个类实现整个应用程序中的每个DAO接口将是一个相当糟糕的设计。
一个更典型的模式是有一个接口(也经常调用)和一个,等等。这些基类将包含查找/获取/读取、保存/存储/持久化、更新/修改和删除/删除/清除等方法。BaseDAO
GenericDAO
JPABaseDAO
JDBCBaseDAO
特定的 DAO 接口(如 then)继承自 和具体实现(如 extends from )。UserDAO
BaseDAO
JPAUserDAO
JPABaseDAO
界面可能如下所示: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();
}
实现此接口的简陋示例: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 实现放在另一个包中。然后,只需在生成中仅包含一个实现包。