之前用過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();
}
好了,到此爲止