我可以使用通用方法来访问休眠中不同实体的数据吗

Posted

技术标签:

【中文标题】我可以使用通用方法来访问休眠中不同实体的数据吗【英文标题】:Can i use generic method to acess data from different entities in hibernate 【发布时间】:2019-11-01 01:28:22 【问题描述】:

例如:我有 User.class 和 Post.Class 我想用休眠状态从这个表中获取所有行。 它是用

完成的
TypedQuery<Post> query = SessionFactory.getCurrentSession().createQuery("from Post");

我还有 dao 层,UserDao 和 PostDao。我有抽象类 CrudDao,方法如下:

public abstract class CrudDao<T> 


    @Transactional
    public void save(T entity) 
        SessionFactory.getCurrentSession().save(entity);
    

所以我的用户和帖子 dao 只是扩展了这个 crudDao,我不需要为他们编写保存方法。当我想获取所有行时,我需要写“来自 MyEntiti”。但是我想让这个方法也抽象,所以我不需要为每个 dao 写多次。但是我不能用抽象方法写“from T”。

我也尝试过这样做:

List<T> getAll(Class<T> type)
    CriteriaQuery<T> criteria = builder.createQuery(type);
    criteria.from(type);
    return 
  SessionFactory.getCurrentSession().createQuery(criteria).getResultList();

所以在我的服务中,我这样称呼我的 dao:

PostDao.getAll(Post.class);

有人告诉我,我的服务不应该知道我的实体,我的 dao 调用服务应该是 PostDao.getAll(); 如果我喜欢这个 ^ 我需要在每个 dao 中编写 getAll 方法,它看起来像很多复制粘贴的代码。

你能给我一些关于如何做或在你的项目中如何做的建议吗?

【问题讨论】:

见this question,如果你不喜欢/不理解/不想要它,那么谷歌搜索一个generic dao 【参考方案1】:

我从 deHaar 的回复中学到了什么: 如果您创建此泛型类型的变量/例如我的泛型 dao,则可以使用泛型 dao 创建抽象方法并调用泛型类:

public abstract class CrudDao<T> 

    private Class<T> type;

    public CrudDao(Class<T> type)
        this.type = type;
    

    @Transactional
    public T getById(,int postId) 
    return sessionFactory.getCurrentSession().get(type, postId);


因此,您只需要编写一个构造函数,该构造函数在您的子 Dao 中调用超类构造函数,以扩展通用 dao。 喜欢:

public class PostCommentDao extends CrudDao<PostComment> 

    public PostCommentDao()
        super(PostComment.class);
    

现在一切都在通用 dao 中运行!

正如塔诺斯所说:为救赎付出很小的代价。

【讨论】:

【参考方案2】:

在我看来,通用 DAO 是一种反模式。 Spring 为您提供了由@Controller(用于 mvc 和 rest)、@Service(用于功能可重用性)和@Repository(用于数据访问)组成的出色的三层架构。可以有更多的代码,只是让它承担一个单一的责任。

【讨论】:

“多一点” - 意味着在每个 DAO 中复制粘贴 CRUD dao opeartions?你是认真的吗? 是的。是一般解决方案无法比拟的。通用的方法总是会有笨拙的代码来解决业务逻辑异常。

以上是关于我可以使用通用方法来访问休眠中不同实体的数据吗的主要内容,如果未能解决你的问题,请参考以下文章

从不同核心数据实体获取数据并将结果转换为相应类的通用方法

来自通用模型定义的两种语言的 ORM 实体类生成器

制作一个适合所有类的通用方法......这可能吗?

通用代码因 Spring 数据和 Querydsl 而失败

我应该使用反射来计算两个或更多实体中存在的属性吗?

如何使用 LINQ to SQL 创建通用数据访问对象 (DAO) CRUD 方法