Single DAO & generic CRUD methods (JPA/Hibernate + Spring)

2022-08-31 22:44:09

在我之前的问题DAO和服务层(JPA / Hibernate + Spring)之后,我决定在使用JPA / Hibernate,Spring和Wicket的应用程序中只为我的数据层使用单个DAO(至少在开始时)。有人提出了通用CRUD方法的使用,但我不太确定如何使用JPA来实现这一点。你能给我一个例子或分享一个关于这个的链接吗?


答案 1

下面是一个示例接口:

public interface GenericDao<T, PK extends Serializable> {
    T create(T t);
    T read(PK id);
    T update(T t);
    void delete(T t);
}

和一个实现:

public class GenericDaoJpaImpl<T, PK extends Serializable> 
    implements GenericDao<T, PK> {

    protected Class<T> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;

    public GenericDaoJpaImpl() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass()
             .getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass
             .getActualTypeArguments()[0];
    }

    @Override
    public T create(T t) {
        this.entityManager.persist(t);
        return t;
    }

    @Override
    public T read(PK id) {
        return this.entityManager.find(entityClass, id);
    }

    @Override
    public T update(T t) {
        return this.entityManager.merge(t);
    }

    @Override
    public void delete(T t) {
        t = this.entityManager.merge(t);
        this.entityManager.remove(t);
    }
}

答案 2

根据文章不要重复DAO,我们使用这种技术已经很多年了。在我们意识到我们犯了一个大错误之后,我们总是在与我们的模式问题作斗争。

通过使用ORM工具,如Hibernate或JPA,您不必分别考虑DAO和服务层。您可以从服务类中使用 EntityManager,因为您知道事务的生命周期以及其中实体类的逻辑。

如果你打电话而不是简单地打电话,你会节省任何一分钟吗?不。您将有一个不必要的 dao 类,它不执行任何其他操作,但将成为 EntityManager 的包装器。不要害怕在 EntityManager(或处于休眠状态的会话)的帮助下在服务类中编写选择。myDao.saveEntityentityManager.saveEntity

还有一点需要注意:您应该定义服务层的边界,不要让程序员返回或等待实体类。UI 或 WS 层程序员根本不应该只了解 DTO-s 的实体类。实体对象具有大多数程序员不知道的生命周期。如果将实体对象存储在会话数据中,并在几秒钟或几小时后尝试将其更新回数据库,则会遇到非常严重的问题。好吧,您可能不会这样做,但是只知道服务层的参数类型和返回类型的UI程序员会保存一些代码行。


推荐