一般在抽取的公共類中會涉及到泛型,而泛型的類型需要用到反射類中的方法確定泛型類型。
/**
* Created by 26685 on 2017/7/4.
*/
/**
* Transactional
* spring中注解是可以繼承的,但是不可以向上延伸。
*
* 既在本抽象類中不加入@Transactional注解,只在子類中加入注解,
* 本類中的方法用到事物會報錯
* javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread
*
* 若只在本類中加入事務控制,不在子類中加注解,
* 子類也會有事務控制
*
*/
@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 編程語言中所有類型的公共高級接口。它們包括原始類型、參數化類型、數組類型、類型變量和基本類型。
* 泛型類內部已自動實現Type接口
* ParameterizedType 是參數化類型,既泛型,繼承Type類
*
* 3. 獲取泛型類
* Type[] getActualTypeArguments() 獲取真實參數類型
*/
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;
}
/**
* 獲取泛型數據庫表名
* 思路:
* 獲取泛型類
* @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() 獲取真實參數類型
*
* @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;
}
}