You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无Spring环境下仅用Hibernate如何实现类似JpaRepository/CrudRepository的通用CRUD功能?

基于Hibernate实现通用泛型DAO的方案

步骤1:定义通用泛型BaseDao接口

接口定义所有通用CRUD方法,泛型参数T为实体类型,ID为主键类型,适配不同实体的主键差异。

import java.util.List;

public interface BaseDao<T, ID> {
    T findById(ID id);
    void save(T entity);
    void update(T entity);
    void delete(T entity);
    List<T> findAll();
}

步骤2:实现BaseDao抽象基类,封装所有通用CRUD逻辑

抽象基类实现BaseDao接口,通过反射获取实际操作的实体Class,解决泛型擦除问题,所有通用方法仅在这里实现一次即可,子类无需重复编写。同时统一使用try-with-resources管理Session,避免资源泄露。

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.lang.reflect.ParameterizedType;
import java.util.List;

public abstract class BaseDaoImpl<T, ID> implements BaseDao<T, ID> {
    private static final Logger log = LogManager.getLogger(BaseDaoImpl.class);
    private final Class<T> entityClass;

    // 构造方法通过反射获取实际的实体Class类型
    @SuppressWarnings("unchecked")
    public BaseDaoImpl() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.entityClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    public T findById(ID id) {
        try (Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession()) {
            return session.get(entityClass, id);
        } catch (Exception e) {
            log.error("查询实体失败", e);
            return null;
        }
    }

    @Override
    public void save(T entity) {
        Transaction transaction = null;
        try (Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            session.save(entity);
            transaction.commit();
        } catch (Exception e) {
            log.error("保存实体失败", e);
            if (transaction != null) transaction.rollback();
        }
    }

    @Override
    public void update(T entity) {
        Transaction transaction = null;
        try (Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            session.update(entity);
            transaction.commit();
        } catch (Exception e) {
            log.error("更新实体失败", e);
            if (transaction != null) transaction.rollback();
        }
    }

    @Override
    public void delete(T entity) {
        Transaction transaction = null;
        try (Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            session.delete(entity);
            transaction.commit();
        } catch (Exception e) {
            log.error("删除实体失败", e);
            if (transaction != null) transaction.rollback();
        }
    }

    @Override
    public List<T> findAll() {
        try (Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession()) {
            return session.createQuery("FROM " + entityClass.getSimpleName(), entityClass).list();
        } catch (Exception e) {
            log.error("查询所有实体失败", e);
            return List.of();
        }
    }
}

步骤3:业务DAO仅需继承基类,无需重复实现CRUD

以UserDao为例:

业务DAO接口

// 直接继承BaseDao,指定实体类型和主键类型即可,有自定义方法再单独加
public interface UserDao extends BaseDao<User, Integer> {
    // 如果有通用CRUD之外的特殊查询方法,在这里定义即可
}

业务DAO实现类

// 继承BaseDaoImpl,实现UserDao接口,无需重写任何通用CRUD方法
public class UserDaoImpl extends BaseDaoImpl<User, Integer> implements UserDao {
    // 如果有自定义方法,在这里实现即可
}

以VpnDao为例:

VpnDao接口

public interface VpnDao extends BaseDao<Vpn, Byte> {
}

VpnDao实现类

public class VpnDaoImpl extends BaseDaoImpl<Vpn, Byte> implements VpnDao {
}

方案优势

  • 所有通用CRUD逻辑仅在BaseDaoImpl中实现一次,20+业务DAO无需重复编写相同代码,后续新增DAO仅需几行核心代码即可完成
  • 自动适配不同实体类型和主键类型,灵活性高
  • 统一Session资源管理、事务处理、异常日志,避免各实现类逻辑不一致的问题
  • 完全基于Hibernate原生能力,无需引入Spring等额外框架

内容的提问来源于stack exchange,提问作者Alexey Zhukov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 22:09:03