泛型和反射在项目中的基本应用之一
2017-07-05 本文已影响0人
乌托邦缤果
一般在抽取的公共类中会涉及到泛型,而泛型的类型需要用到反射类中的方法确定泛型类型。
/**
* 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;
}
}