美文网首页
泛型和反射在项目中的基本应用之一

泛型和反射在项目中的基本应用之一

作者: 乌托邦缤果 | 来源:发表于2017-07-05 17:34 被阅读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;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:泛型和反射在项目中的基本应用之一

          本文链接:https://www.haomeiwen.com/subject/sbbqhxtx.html