• Java反射机制、注解及JPA实现


    1、java反射概述

      JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

      Java的反射机制允许编程人员在对类未知的情况下,获取类相关信息的方式变得更加多样灵活,调用类中相应方法,是Java增加其灵活性与动态性的一种机制。

    2、java注解

      注解本身没有任何的作用。简单说和注释没啥区别,而它有作用的原因是:注解解释类,也就是相关对代码进行解释的特定类。一般这些类使用反射是可以拿到的。Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。

    3 、反射结合注解、自实现JPA、实体映射

      话不多说、直接上干货

      注解TableEntry:用于解释实体的表名

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    public @interface TableEntry {
        
        String tableName();
        
    }

     ·PKField注解:用于解释主键及主键生成规则

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @Documented
    public @interface PKField {
        
    /*    "ORCLE_SEQUENCE",
        "MYSQL_AUTO_INCREASING",
        "SELECTED_INCREASING",
        "CURE_UUID"*/
        PkGeneratorEnum pkGenerator() default PkGeneratorEnum.SEQUENCE;
        
        String sequenceName() default "";
    
    }

      ColumnField注解:用于解释实体字段和数据库字段的对应

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @Documented
    public @interface ColumnField {
        
        String columnName();
        
    }

      Transient注解:用于描述无需查询出的实体属性

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @Documented
    public @interface Transient {
        
        String value() default "";
        
    }

     实体映射接口

      定义接口用于 获取实体

    • 对应的表名
    • 主键
    • 主键生成规则
    • sequence名
    public interface EntryMapper {
    
         abstract String getEntryTableName(Class<?> clazz);
        
         
         abstract String[] getPKFieldName(Class<?> clazz);
            
        
         abstract String getSequenceName(Class<?> clazz);
          
         abstract PkGeneratorEnum getPkGenerator(Class<?> clazz);
    }

    实体映射接口实现类

      通过反射获取注解对应作用域提供的信息

    public class JpaEntryMapper implements EntryMapper{
    
        public  String getEntryTableName(Class<?> clazz){
           
            Assert.notNull(clazz, "clazz不能为空");
            
            TableEntry  tableAnno=(TableEntry) clazz.getAnnotation(TableEntry.class); 
            
            Assert.notNull(tableAnno, "TableEntry注解未设置");
            Assert.state(StringUtil.isNotEmpty(tableAnno.tableName()), "tableAnno.tableName未设置");
    
            return StringUtil.toUpperCase(tableAnno.tableName());
        }
        
        
    
        
        public  String[] getPKFieldName(Class<?> clazz){
            
            Assert.notNull(clazz, "clazz不能为空");
            Field[]  fields= clazz.getDeclaredFields();
            int pkArrLen=(fields.length>10?10:fields.length);
        //    String[] pkArr=new String[pkArrLen];
            
            List<String> pk_list = new ArrayList<String>(pkArrLen);
            
            for(int i=0; i < fields.length ; i++){
                if("serialVersionUID".equalsIgnoreCase(fields[i].getName()))continue;
    
                PKField pkField = fields[i].getAnnotation(PKField.class);
                
                if(pkField != null){
                    ColumnField columnField = fields[i].getAnnotation(ColumnField.class);
                    
                    if(columnField==null){
                        //未设置columnField注解默认属性值
                        pk_list.add(StringUtil.toLowerCase(fields[i].getName()));
                    }else{
                        pk_list.add(StringUtil.toLowerCase(columnField.columnName()));
                    }
                }
            }
            Assert.notEmpty(pk_list, "PKField未设置或ColumnField未设置");
            return pk_list.toArray(new String[0]);
        }
        
        public  String getSequenceName(Class<?> clazz){
            Assert.notNull(clazz, "clazz不能为空");
    
            Field[]  fields= clazz.getDeclaredFields();
            for(Field field : fields){
                if("serialVersionUID".equalsIgnoreCase(field.getName()))continue;
                PKField pkField = field.getAnnotation(PKField.class);
                
                if(pkField != null){
                    if(StringUtil.isNotEmpty(pkField.sequenceName())){
                        return StringUtil.toUpperCase(pkField.sequenceName());
                    }
                    
                }
            }
            Assert.state(false, "pkField.sequenceName未设置");
            return null;
        }
        
        public  PkGeneratorEnum getPkGenerator(Class<?> clazz){
            Assert.notNull(clazz, "clazz不能为空");
    
            Field[]  fields= clazz.getDeclaredFields();
            for(Field field : fields){
                if("serialVersionUID".equalsIgnoreCase(field.getName()))continue;
                PKField pkField = field.getAnnotation(PKField.class);
                
                if(pkField != null){
                //    Assert.notNull(pkField.pkGenerator(), "pkField.pkGenerator未设置");
                    if(pkField.pkGenerator()!=null){
                        return pkField.pkGenerator();
                    }
                }
            }
            Assert.state(false, "PKField未设置");
            return null;
        }
      }

    抽象sql中的where 条件 和 whereUnit单元

    Where类

    public class Where {
        
        
        private List<WhereUnit> whereUnitList ;
        private boolean isNamed = false ;
        
        public Where(){
            whereUnitList = new ArrayList<WhereUnit>() ;
        }
        
        public Where(boolean isNamed){
            this();
            this.isNamed=isNamed;
        }
        
        public Where(Object inputDto,boolean isNamed){
            this(isNamed);
            initEntry(inputDto);
        }
        
        public Where(Object inputDto){
            this();
            initEntry(inputDto);
        }
        
        public Where and(String colName ,String comparator ,Object colVal)
        {
            
            add(new WhereUnit("AND",colName,comparator,colVal));
            
            return this;
        }
        
        public Where or(String colName ,String comparator ,Object colVal)
        {
            add(new WhereUnit("OR",colName,comparator,colVal));
            return this;
        }
        
        public boolean add(WhereUnit unit)
        {
            return whereUnitList.add(unit);
        }
        
        public WhereUnit get(int index)
        {
            return whereUnitList.get(index);
        }
        
        public WhereUnit set(int index,WhereUnit unit)
        {
            if(index<0 || index >= size() ){
                throw new IndexOutOfBoundsException("setUnit的index超出List的长度");
            }
            return whereUnitList.set(index, unit);
        }
        
        public Iterator<WhereUnit> iterator(){
            return whereUnitList.iterator();
        }
        
        public WhereUnit remove(int index)
        {
            return whereUnitList.remove(index);
        }
        
        public boolean remove(WhereUnit unit)
        {
            return whereUnitList.remove(unit);
        }
        
        public int size()
        {
            return whereUnitList.size();
        }
        
        public int indexOf(WhereUnit unit)
        {
            return whereUnitList.indexOf(unit);
        }
        
        
        public StringBuffer toSqlString(){
            
            StringBuffer where_Buffer=new StringBuffer(" WHERE 1=1 ");
            Iterator<WhereUnit> iter=whereUnitList.iterator();
            
            while(iter.hasNext()){
                WhereUnit unit = iter.next();
                Assert.notNull(unit,"WhereUnit不未空");
                
                where_Buffer.append(unit.toSqlString(this.isNamed));
                
            }
            
            return where_Buffer;
        }
        
        public Object[] getParamterValArr(){
            List<Object> paras= new ArrayList<Object>(size());
            Iterator<WhereUnit> iter = whereUnitList.iterator();
            
            while(iter.hasNext()){
                WhereUnit unit =iter.next();
                if("IN".equalsIgnoreCase(unit.getComparetor())){
                    continue;
                }
                paras.add(unit.getColVal());
            }
            return paras.toArray();
            
        }
        
        public Map<String,Object> getParamterMap(){
            Map<String,Object> para_map= new HashMap<String,Object>(size());
            Iterator<WhereUnit> iter = whereUnitList.iterator();
            
            while(iter.hasNext()){
                WhereUnit unit =iter.next();
                if("IN".equalsIgnoreCase(unit.getComparetor())){
                    continue;
                }
                para_map.put( unit.getColName(),unit.getColVal());
            }
            return para_map;
            
        }
        
        private void initEntry(Object entry) {
            // TODO
            Assert.notNull(entry, "entry不为空");
            Assert.notNull(whereUnitList, "whereUnitList不为空");
            
            Class<?> entry_class = entry.getClass();
            try{
                 Field[] fields = entry_class.getDeclaredFields();
                 for(Field field : fields){
                     String field_name =  field.getName();
                    if(field_name.equalsIgnoreCase("serialVersionUID"))continue;
                    
                    String read_method_name = "get"+StringUtil.toUpperFristChar(field_name);
                    Method  read_method= entry_class.getDeclaredMethod(read_method_name);
                    
                    Object    field_val = read_method.invoke(entry);
                     if ( field_val != null ){
                         ColumnField columnFieldAnno = field.getAnnotation(ColumnField.class);
                         if(columnFieldAnno == null){
                             and(field_name,"=",field_val);
                         }else{
                             and(columnFieldAnno.columnName(),"=",field_val);
                         }
                        
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
        
    }

    WhereUnit类

    public class WhereUnit {
        
        private String colName;
        
        private String comparetor;
        
        private String linkSign;
        
        private Object colVal;
    
        public WhereUnit(){}
        
        public WhereUnit(String linkSign, String colName , String comparetor,Object colVal){
            this.linkSign=linkSign;
            this.colName=colName;
            this.comparetor=comparetor;
            this.colVal=colVal;
        }
        
        public String getColName() {
            return colName;
        }
    
        public void setColName(String colName) {
            this.colName = colName;
        }
    
    
        public Object getColVal() {
            return colVal;
        }
    
        public void setColVal(Object colVal) {
            this.colVal = colVal;
        }
    
        public String getComparetor() {
            return comparetor;
        }
    
        public void setComparetor(String comparetor) {
            this.comparetor = comparetor;
        }
    
        public String getLinkSign() {
            return linkSign;
        }
    
        public void setLinkSign(String linkSign) {
            this.linkSign = linkSign;
        }
        
        public StringBuffer toSqlString(boolean isNamed){
             StringBuffer unit_Buffer = new StringBuffer(); 
             unit_Buffer.append(" ").append(linkSign).append(" ").append(colName).append(" ").append(comparetor);
             if("IN".equalsIgnoreCase(comparetor)){
                 unit_Buffer.append(" (").append(colVal).append(") ");;
             }else{
                 if(isNamed){
                     unit_Buffer.append(" :"+colName+" ");
                 }else{
                     unit_Buffer.append(" ? ");
                 }
             }
                 
             return unit_Buffer;
        }
        
    }

    JpaService接口定义常用的方法

    public interface JpaService {
    
        <T> T findById(Class<T> clazz, Long id);
        
        <T> T findById(Class<T> clazz, Where pks_where);
        
        <T> T findById(Class<T> clazz, Long id, Boolean cascade);
        
        <T> T findById(Class<T> clazz, Where pks_where, Boolean cascade);
        
        <T> List<T> findList(T inputDto);
        
        <T> List<T> findList(Class<T> clazz, Where where, OrderBy orderby);
    
        <T> List<T> findList(Class<T> clazz, Where where);
    
        List<Map<String,Object>> findList(String tableName, Where where, OrderBy orderby);
    
        List<Map<String,Object>> findList(String tableName, Where where);
        
    
        <T> List<T> findAll(Class<T> clazz);
    
        <T> List<T> findAll(Class<T> clazz, OrderBy orderby);
    
        List<Map<String,Object>> findAll(String tableName);
    
        List<Map<String,Object>> findAll(String tableName, OrderBy orderby);
        
    
        <T> Pager<T> findPager(Class<T> clazz, Pager<T> pager, Where where);
    
        <T> Pager<T> findPager(Class<T> clazz, Pager<T> pager);
    
        <T> Pager<T> findPager(Class<T> clazz, Pager<T> pager, Where where,
                OrderBy orderby);
    
        
        Long selectTotal(String tableName, Where where);
    
        Long selectTotal(Class<?> clazz, Where where);
        
    
        <T> List<T> selectPageList(Class<T> clazz, Pager<T> pager, Where where,
                OrderBy orderby);
    
        int insert(Object entry);
        
        int insert(Class<?> clazz,SqlSet sql_set);
        
        int update(Object entry);
        
        int update(Class<?> clazz, SqlSet sql_set);
        
        long insertUseKey(Object t);
        
        long insertUseKey(Class<?> clazz, SqlSet sql_set);
    
        int delete(Class<?> clazz, Long id);
        
        int delete(Class<?> clazz, Where pk_where);
        
        Long getSeq(Class<?> clazz);
    }

    实现JpaService的接口,就能愉快的通过jpaService直接调用常用的方法啦


    我是飞奔的企鹅:

        一只有梦想,有故事的企鹅 ,欢迎诉说你的故事

  • 相关阅读:
    Java 动态代理机制分析及扩展
    记:从百度空间搬家到博客园写博客要写的舒服
    字符串与byte[]之间的转换
    关于中文的几个编码GB2312、GBK、GB18030、GB13000
    深入biztalk中各种端口绑定方式(七) 直接绑定之Partner Orchestration
    X.509 数字证书结构和实例
    深入biztalk中各种端口绑定方式(六) 直接绑定之Self Correlating
    在代码中使用biztalk类库建立Message和Part
    Byte[]和BASE64之间的转换
    深入biztalk中各种端口绑定方式(五) 直接绑定之MessageBox
  • 原文地址:https://www.cnblogs.com/flyPenguinblog/p/11164239.html
Copyright © 2020-2023  润新知