【问题标题】:Creating a generic DAO for JPA that I can inherit from为 JPA 创建一个可以继承的通用 DAO
【发布时间】:2012-10-25 18:26:39
【问题描述】:

我正在尝试创建一个可以继承的存储库类,以从中获取基本的 CRUD 功能。 EntityManager.find(..) 需要一个 Class 参数。但是,您不能将T 传递给它(由于某种原因,我还不明白......类型擦除)。所以我找到了返回实体类的方法,并从我看到的另一个问题中添加了它。首先,它是如何工作的,其次它会对性能产生多大影响?我看到它使用反射。

@Stateless
public abstract class AbstractSqlRepository<T> implements Repository<T> {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void create(T entity) {
        entityManager.persist(entity);
    }

    @Override
    public T find(int id) {
        return entityManager.find(getEntityClass(), id);
    }

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

    @Override
    public void remove(T entity) {
        entityManager.remove(entity);
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public Class<T> getEntityClass() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();

        return (Class<T>) genericSuperclass.getActualTypeArguments()[0];
    }
}

新方法:

@Stateless
public abstract class AbstractSqlRepository<T> implements Repository<T> {

    @PersistenceContext
    private EntityManager entityManager;
    private Class<T> clazz;

    public AbstractSqlRepository(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public void create(T entity) {
        entityManager.persist(entity);
    }

    @Override
    public T find(int id) {
        return entityManager.find(clazz, id);
    }

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

    @Override
    public void remove(T entity) {
        entityManager.remove(entity);
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }
}

公共类 QuestionSqlRepository 扩展 AbstractSqlRepository 实现 QuestionRepository {

public QuestionSqlRepository() {
    super(Question.class);
}

}

这是一个不好的方法吗?

【问题讨论】:

  • 反射会对性能产生影响。您将不得不尝试查看它是否对您的项目影响太大。好主意!
  • 没有那么优雅,你总是可以在构造函数中设置一个 Class classType 对象。子类构造器只需要调用 super(this.getClass())。它会比使用反射更快,但在开发过程中多了一个步骤。

标签: java jakarta-ee jpa


【解决方案1】:

据说反射会增加开销,但我认为您不必每次都获取对象的类。

第一次找到它,然后检查是否为空,与调用超类方法相比,这增加了很少的开销。

反对构造函数参数的唯一论据是你的类不会是 POJO。

这里是示例代码:

@SuppressWarnings("unchecked")
public class HibernateBaseDao<T, Pk extends Serializable> implements Dao<Pk, T> {

    // ...
    private Class<T> type;

    // ...

    public Class<T> getType() {

        if (this.type == null) {

            ParameterizedType parameterizedType = (ParameterizedType) (this
                    .getClass().getGenericSuperclass());

            while (!(parameterizedType instanceof ParameterizedType)) {
                parameterizedType = (ParameterizedType) parameterizedType
                        .getClass().getGenericSuperclass();
            }

            this.type = (Class<T>) parameterizedType.getActualTypeArguments()[0];

        }

        return this.type;
    }

    @Override
    public T load(Pk id) {

        return (T) this.sessionFactory.getCurrentSession().load(this.getType(),
                id);
    }

    @Override
    public T get(Pk id) {
        return (T) this.sessionFactory.getCurrentSession().get(this.getType(),
                id);
    }

}

【讨论】:

    猜你喜欢
    • 2014-08-16
    • 1970-01-01
    • 2010-12-10
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多