一般在抽取的公共類中會涉及到泛型拼坎,而泛型的類型需要用到反射類中的方法確定泛型類型握联。
/**
* Created by 26685 on 2017/7/4.
*/
/**
* Transactional
* spring中注解是可以繼承的,但是不可以向上延伸。
*
* 既在本抽象類中不加入@Transactional注解,只在子類中加入注解依痊,
* 本類中的方法用到事物會報錯
* javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread
*
* 若只在本類中加入事務(wù)控制,不在子類中加注解怎披,
* 子類也會有事務(wù)控制
*
*/
@Transactional
public abstract class DaoImpl<T> implements Dao<T> {
@PersistenceContext
protected EntityManager em;
protected Class<T> entityClass = getEntityClass();
public void add(T entity) {
em.persist(entity);
}
public void delete(Serializable id) {
em.remove(em.getReference(entityClass,id));
}
public T update(T entity) {
return em.merge(entity);
}
@Transactional(propagation= Propagation.NOT_SUPPORTED)
public T findOne(Serializable id) {
return em.find(entityClass,id);
}
@Transactional(propagation= Propagation.NOT_SUPPORTED)
public long getCount() {
return (Long)em.createQuery("select count(1) from "+ getEntityName() +" o").getSingleResult();
}
/**
* 獲取泛型類型
* 思路:
* BuyerServiceImpl extends DaoImpl<Buyer>
* 通過子類獲取泛型
* 1. 獲取子類Class胸嘁,既BuyerServiceImpl
* getClass() 獲取運行時類
*
* 2. 獲取抽象類,抽象類包括泛型 凉逛,既DaoImpl<Buyer>
* Type getGenericSuperclass() 獲取帶有泛型的父類
* Type是 Java 編程語言中所有類型的公共高級接口性宏。它們包括原始類型、參數(shù)化類型鱼炒、數(shù)組類型衔沼、類型變量和基本類型蝌借。
* 泛型類內(nèi)部已自動實現(xiàn)Type接口
* ParameterizedType 是參數(shù)化類型昔瞧,既泛型,繼承Type類
*
* 3. 獲取泛型類
* Type[] getActualTypeArguments() 獲取真實參數(shù)類型
*/
public Class<T> getEntityClass(){
Type type = this.getClass().getGenericSuperclass();
if(type instanceof ParameterizedType){
ParameterizedType pt = (ParameterizedType)type;
return (Class<T>) pt.getActualTypeArguments()[0];
}
return null;
}
/**
* 獲取泛型數(shù)據(jù)庫表名
* 思路:
* 獲取泛型類
* @Entity
* public class Buyer {}
* 通過泛型類獲得注解Entity,獲取Entity的屬性name
*
* 1. 獲取泛型類
* Class<T> getEntityClass()
*
* 2. 獲得注解Entity
* <A extends Annotation> A getAnnotation(Class<A> annotationClass)
*
* 3. 判斷Entity的name屬性是否為空菩佑,非空的話自晰,name值就是表名稱
* Type[] getActualTypeArguments() 獲取真實參數(shù)類型
*
* @return
*/
public String getEntityName(){
String entityName = getEntityClass().getSimpleName();
Entity clazz = getEntityClass().getAnnotation(Entity.class);
if(null!=clazz.name()&&clazz.name().trim().length()>0){
entityName=clazz.name();
}
return entityName;
}
}