java - 如何使用泛型实现 Hibernate DAO

标签 java spring hibernate generics dao

我找到了一些关于如何使用泛型构建 Hibernate DAO 的教程,但它们都使用 EntityManager 而不是 SessionFactory。我的问题是如何使用 SessionFactory 构建带有泛型的 DAO。到目前为止,我有以下内容:

接口(interface):

public interface GenericDao<T> {

    public void save(T obj);
    public void update(T obj);
    public void delete(T obj);
    public T findById(long id);
}

类:

@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {

    @Autowired
    private SessionFactory sessionFactory;

    public void save(T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.save(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public void update(T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.update(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public void delete(T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.delete(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public T findById(long id) {
        // ??
        return null;
    }

我不确定如何使用泛型来处理findById。我相信其他方法是正确的,但如果我错了请纠正我。

附带问题:使用 EntityManager 是否比使用 SessionFactory 更有益?我看到了一些关于这个主题的帖子,但想要更多的意见。

最佳答案

您需要有权访问 Class<T>从那个方法中。你有两个选择,你可以通过 Class<T>进入方法:

public T findById(long id, Class<T> clazz) {
    // method implementation
}

或者您可以传递 Class<T>进入类的构造函数以在方法中使用:

@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {

    private Class<T> clazz;

    protected GenericDaoImpl(Class<T> clazz) {
        this.clazz = clazz;
    }

    // other methods omitted

    public T findById(long id) {
        // method implementation
    }
}

子类会将它们的类传递给父类(super class):

public class UserDao extends GenericDaoImpl<User> {
    public UserDao() {
        super(User.class);
    }
}

然后,使用您的 clazz例如,您可以使用 Session#get 在通用方法中获取实体方法:

T entity = session.get(clazz, id);

有关详细信息,请参阅以下问题:


至于附带问题,EntityManager是 JPA(Java 持久性 API)的一部分。使用 Java API 规范而不是 Hibernate API 开发您的应用程序允许您的应用程序不依赖于 Hibernate。这允许您在 Hibernate、OpenJPA 或 TopLink 等流行的 JPA 实现之间切换,而无需对代码进行更改。

This question有更多关于差异的信息。

关于java - 如何使用泛型实现 Hibernate DAO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38044194/

相关文章:

java - 如何合并和验证 swt 对话框的两个文本字段?

java - 如何在JList中设置背景颜色和字体大小?

Java多线程纠错——线程安全单例

java - 用java监控系统的平台访问和花费时间

java - 如何在 Spring 中定义多个 sessionfactory 实例?

java - 如何将 bean 加载到测试上下文中?

java - application.properties 被忽略,取自别处

mysql - 如何将 Varchar 的长度限制在 2 到 100 之间

java - Hibernate 类型解析器

java - 使用 @Query 在 intellij 中进行语言注入(inject)