之前用过mybatis-plus,里面有个通用dao类,直接继承就可以实现简单的增删改查,当时只是用,但是现在做项目是hibernate,而且是原生的那种。。
大概有几十个表,把几十个dao写入简单的增删改查,怎么感觉就是代码臃肿,
于是我想了想,可以泛型加反射
用泛型的目的是我们不确定操作那个entity,那么我们用了泛型之后就知道了,只需要在类上加上就行了
用反射就是要获取泛型的类型,也就是说在实际运用中,是可以得到传入的类型,为什么要这样,是因为我们查的是要操作的entity的class,现在我们有个问题了,怎么获取传入的实际泛型类型,百度了一下,搜了个工具类
package com.zhizhuo.util;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class GenericsUtils {
/**
* 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends
* GenricManager<Book>
*
* @param clazz The class to introspect
* @return the first generic declaration, or <code>Object.class</code> if cannot be determined
*/
public static Class getSuperClassGenricType(Class clazz) {
return getSuperClassGenricType(clazz, 0);
}
/**
* 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
*
* @param clazz clazz The class to introspect
* @param index the Index of the generic ddeclaration,start from 0.
*/
public static Class getSuperClassGenricType(Class clazz, int index)
throws IndexOutOfBoundsException {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
return Object.class;
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}
}
下面实现
BaseDao
package com.zhizhuo.dao;
import com.zhizhuo.dao.impl.DepartmentDaoImpl;
import com.zhizhuo.model.entity.Department;
import com.zhizhuo.util.GenericsUtils;
import com.zhizhuo.util.HibernateSessionFactory;
import com.zhizhuo.util.PageHelper;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projections;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.Root;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @作者 1543057945
* @时间 2019/12/18 14:50
* @param <T>
*/
public abstract class BaseDao<T> {
private Class clazz;
/**
* 初始化
*/
public BaseDao() {
//获取该类上标注的泛型类型
Class clazz = GenericsUtils.getSuperClassGenricType(getClass());
this.clazz=clazz;
System.out.println(clazz);
}
public Session getSession() {
return HibernateSessionFactory.getSession();
}
/**
* 插入方法
* @param t
* @return 插入的主键
*/
public Serializable insert(T t) {
return getSession().save(t);
}
/**
* 更新方法
* @param t
*/
public void updateById(T t) {
getSession().update(t);
}
/**
* 删除
* @param t
*/
public void deleteById(T t) {
getSession().delete(t);
}
/**
* 批量删除
* @param ids
* @return
*/
public int deleteByIds(List<T> ids){
CriteriaDelete crd = getSession()
.getEntityManagerFactory()
.createEntityManager()
.getCriteriaBuilder()
.createCriteriaDelete(clazz);
Root root = crd.from(clazz);
//创建表达式
crd.where(root.in(ids));
return getSession().createQuery(crd).executeUpdate();
}
/***
* 通过id查找
* @param id
* @return
*/
public T findById(Serializable id) {
return (T) getSession().get(this.clazz, id);
}
/**
* 查找全部
* @return
*/
public List<T> findAll(){
return getSession().createCriteria(this.clazz).list();
}
/**
* 分页查询
* @param ph
* @return
*/
public List<T> findPageList(PageHelper ph){
Criteria cr = getSession().createCriteria(this.clazz);
cr.setFirstResult(ph.getStartIndex());
cr.setMaxResults(ph.getPageSize());
return cr.list();
}
/**
* 分页查询
* @param startIndex 开始索引
* @param effset 偏移量
* @return
*/
public List<T> findPageList(int startIndex,int effset){
Criteria cr = getSession().createCriteria(this.clazz);
cr.setFirstResult(startIndex);
cr.setMaxResults(effset);
return cr.list();
}
/**
* 查询总条数
* @return
*/
public Long findCount(){
return (Long) getSession()
.createCriteria(clazz)
.setProjection(Projections.rowCount())
.uniqueResult();
}
public static void main(String[] args) {
Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
List<String> list= Arrays.asList("297e0cf76f17c400016f17f5464f0000","297e0cf76f17c400016f17f551980001");
BaseDao<Department> departmentDao = new DepartmentDaoImpl();
List<Department> collect = list.stream().map(e -> {
Department department = new Department();
department.setDepartmentId(e);
return department;
}).collect(Collectors.toList());
departmentDao.deleteByIds(collect);
tx.commit();
HibernateSessionFactory.closeSession();
}
}
使用的话就是
很重要:BaseDao<> 尖括号里面就是要操作的entity,在BaseDao里面的构造器可以或得到这个类型
测试
public static void main(String[] args) {
Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
List<String> list= Arrays.asList("297e0cf76f17c400016f17f5464f0000","297e0cf76f17c400016f17f551980001");
BaseDao<Department> departmentDao = new DepartmentDaoImpl();
List<Department> collect = list.stream().map(e -> {
Department department = new Department();
department.setDepartmentId(e);
return department;
}).collect(Collectors.toList());
departmentDao.deleteByIds(collect);
tx.commit();
HibernateSessionFactory.closeSession();
}
好了,到此为止