上次我使用 JBoss 7.1(Java EE6 标准)开发应用程序时,我使用 DAO 编写了持久层。
首先,我有一个“抽象”DAO,它是所有具体 daos 之父:
public abstract class AbstractDao<T> {
private Class<T> entityClass;
private String defaultSortColumn;
public AbstractDao(Class<T> entityClass) {
this.entityClass = entityClass;
this.defaultSortColumn = "";
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
@SuppressWarnings("rawtypes")
public List<T> find() {
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root from = cq.from(entityClass);
cq.select(from);
return getEntityManager().createQuery(cq).getResultList();
}
@SuppressWarnings("rawtypes")
public int count() {
//...
}
}
然后我为我的域中的每个数据库实体都有一个 dao 实现。
它们彼此都非常相似,它们只是为查询添加了比通常的“crud”操作更复杂的方法。
这是一个例子:
@Stateless
public class ShopDao extends AbstractDao<Shop> {
@Inject
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
public ShopDao() {
super(Shop.class);
}
}
如您所见,我的 DAO 是无状态 EJB。
这种方式使我的应用程序工作,但是......当我必须创建一个新实体时,我必须同时创建实体本身和 DAO。是不是有点多余?但是,我想不出更好的方法,因为我经常需要对特定实体进行复杂的查询。
问题是:
这是最佳做法吗?我还能如何设计我的持久层?
DAO 成为 EJB 好不好?
我在客户端(JSF 控制器)进行了验证。它应该在持久层吗?如何?
将原始 EntityManager 放在服务层类中会更好吗,避免 DAO?
编辑
有没有办法避免每张桌子都有一个道?