Hibernate增删改查CRUD通用DAO实现

2022-05-09 448点热度 0人点赞 0条评论

需求描述

Hibernate下的程序,可能有很多实体类,每个实体类的相关基础的增删改查操作,按照一般的做法,都是要分别写Dao方法,然后实现增删改查的操作(例如sessionFactory.getCurrentSession().get/save/delete等等),我们可以看到这些操作都是很类似的,有没有什么办法可以把这些抽取出来重构下,减少重复操作,提高效率。

实现

利用Java的泛型,将实体类提出出一个公共的BaseEntity.java,后续具体的实体类都extends这个BaseEntity。

定义BaseDao,这时interface接口,我们定义了几个常用的方法,例如保存:saveBaseEntity,删除:deleteBaseEntity,根据ID查找:getBaseEntityById,列表:listBaseEntities,找行数:countBaseEntities

IBaseDao.java:

public interface IBaseDao {

    Session getSession();

    void saveBaseEntity(BaseEntity baseEntity);

    void deleteBaseEntity(BaseEntity baseEntity);

    <T extends BaseEntity> T getBaseEntityById(Class<T> type, Long id);

    <T extends BaseEntity> List<T> listBaseEntities(Class<T> type, int start, int limit, String sortColumn, String sortDirection);

    <T extends BaseEntity> long countBaseEntities(Class<T> type);
}

下面是实现类:BaseDaoImpl.java

@Component("baseDao")
public class BaseDaoImpl implements IBaseDao {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public void saveBaseEntity(BaseEntity baseEntity) {
        if (baseEntity.getId() == null) {
            baseEntity.setCreateDate(new Date());
        } else {
            baseEntity.setUpdateDate(new Date());
        }
        sessionFactory.getCurrentSession().saveOrUpdate(baseEntity);
    }

    @Override
    public void deleteBaseEntity(BaseEntity baseEntity) {
        sessionFactory.getCurrentSession().delete(baseEntity);
    }

    @Override
    public <T extends BaseEntity> T getBaseEntityById(Class<T> type, Long id) {
        return sessionFactory.getCurrentSession().get(type, id);
    }

    @Override
    public <T extends BaseEntity> List<T> listBaseEntities(Class<T> type, int start, int limit, String sortColumn, String sortDirection) {
        StringBuilder hql = new StringBuilder("from " + type.getName() + " t where 1=1");
        if (!StringUtils.isEmpty(sortColumn)) {
            hql.append(" order by t.").append(sortColumn).append(" ").append(sortDirection).append(", id asc");
        } else {
            hql.append(" order by t.id asc");
        }
        Query query = sessionFactory.getCurrentSession().createQuery(hql.toString());
        query.setFirstResult(start);
        if (limit > 0) {
            query.setMaxResults(limit);
        }
        return query.list();
    }

    @Override
    public <T extends BaseEntity> long countBaseEntities(Class<T> type) {
        Query query = sessionFactory.getCurrentSession().createQuery("select count(t) from " + type.getName() + " t where 1=1");
        return (Long) query.uniqueResult();
    }

}

BaseEntity.java

这是所有实体类的基类BaseEntity,我这边规定基类都有Long类型的id,还有createDate, updateDate,这个可以根据自己的实际情况进行修改

public class BaseEntity implements Serializable {
    private Long id; //ID
    private Date createDate; // 记录新增时间
    private Date updateDate; // 记录修改时间

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "create_date")
    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    @Column(name = "update_date")
    public Date getUpdateDate() {
        return updateDate;
    }

    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }
}

使用方法

以上是准备工作,下面看具体的调用,以一个Student实体类为例:

Student.java

@Entity
@Table(name = "t_test")
public class Student extends BaseEntity {
    private String name; //姓名
    private int age;//年龄

    private Long id;
    private Date createDate;
    private Date updateDate;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "create_date")
    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    @Column(name = "update_date")
    public Date getUpdateDate() {
        return updateDate;
    }

    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Service中的调用示例:

@Resource(name = "baseDao")
private IBaseDao baseDao;

public void test() {
    // 新增学生示例
    Student student = new Student();
    student.setAge(18);
    student.setName("Terry");
    baseDao.saveBaseEntity(student);

    // 根据ID查找学生示例
    Student queryStudent = baseDao.getBaseEntityById(Student.class, 1L);

    // 删除学生示例
    baseDao.deleteBaseEntity(student);

    // 查找所有学生示例,根据年龄排序
    List<Student> students = baseDao.listBaseEntities(Student.class, 0, 10, "age", "asc");
    
    //学生总数
    long countStudent = baseDao.countBaseEntities(Student.class);
}

可以看到,这种简单的增删改查方法,都不需要新增dao,直接使用baseDao就可以做到了。

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论