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直接调用常用的方法啦


我是飞奔的企鹅:

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

原文地址:https://www.cnblogs.com/flyPenguinblog/p/11164239.html