• 使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句


    这次给大家介绍一下在Java开发过程中 使用自定义注解开发:
    主要知识点:
                1.反射            主要用于提取注解信息
                2.自定义异常  主要是为了自己自定义一个异常信息
                3.自定义注解  本次重点 学会如何自定义注解以及如何使用反射提取注解信息运用到实际开发
    下图表示在Java中注解的含义以及注解的分类和如何解析注解

    通常我们使用自定义注解一般使用4中元注解即:
    @Target
    @Retention
    @Documented
    @Inherited

      1 **
      2  * 
      3  */
      4 /**
      5  * ClassName:package-info.java
      6  * @author xg.qiu
      7  * @since JDK1.7
      8  * Aug 3, 2015
      9  * 使用自定义注解:
     10  * @Target :用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
     11  * 取值(ElementType)有:
     12         1.ElementType.CONSTRUCTOR:用于描述构造器
     13         2.ElementType.FIELD:用于描述域
     14         3.ElementType.LOCAL_VARIABLE:用于描述局部变量
     15         4.ElementType.METHOD:用于描述方法
     16         5.ElementType.PACKAGE:用于描述包
     17         6.ElementType.PARAMETER:用于描述参数
     18         7.ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
     19   @Retention :@Retention定义了该Annotation被保留的时间长短
     20   取值(RetentionPoicy)有:
     21     1.RetentionPolicy.SOURCE:在源文件中有效(即源文件保留)
     22     2.RetentionPolicy.CLASS:在class文件中有效(即class保留)
     23     3.RetentionPolicy.RUNTIME:在运行时有效(即运行时保留)
     24   @Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,
     25                   因此可以被例如javadoc此类的工具文档化。
     26                   Documented是一个标识注解,没有成员。
     27   @Inherited :元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的
     28                   [必须是extend class 而不是implements interface]
     29  */
     30 package com.demo.ann;
     31 
     32 注解语法:
     33 public @interface 注解名{
     34    
     35         // 注解变量
     36        // 元数据类型:基本数据类型 String class enum Annotation 以及上述类型数组
     37        // 如果元数据只有一个时 必须声明为value();
     38 }
     39 
     40 /**
     41  * 
     42  */
     43 package com.demo.ann.anns;
     44 
     45 import java.lang.annotation.ElementType;
     46 import java.lang.annotation.Retention;
     47 import java.lang.annotation.RetentionPolicy;
     48 import java.lang.annotation.Target;
     49 
     50 /**
     51  * ClassName:Table.java
     52  * @author xg.qiu
     53  * @since JDK1.7
     54  * Aug 3, 2015
     55  * 自定义注解:表
     56  * 用法:
     57  *  @Table("user")
     58  *     public class User
     59  */
     60 
     61 @Target( ElementType.TYPE)// 作用域 类或接口
     62 @Retention( RetentionPolicy.RUNTIME)// 有效期为运行时
     63 public @interface Table {
     64     String value();
     65 }
     66 
     67 
     68 
     69 /**
     70  * 
     71  */
     72 package com.demo.ann;
     73 
     74 import com.demo.ann.anns.Column;
     75 import com.demo.ann.anns.Table;
     76 
     77 /**
     78  * ClassName:User.java
     79  * JAVABean 用户实体类
     80  * @author xg.qiu
     81  * @since JDK1.7 Aug 3, 2015
     82  */
     83 @Table("TABLE_USER")
     84 public class User {
     85     @Column("USER_ID")
     86     private int userId;
     87     @Column("USER_NAME")
     88     private String userName;
     89     @Column("PASS_WORD")
     90     private String passWord;
     91     @Column("AGE")
     92     private int age;
     93 
     94     public int getUserId() {
     95         return userId;
     96     }
     97 
     98     public void setUserId(int userId) {
     99         this.userId = userId;
    100     }
    101 
    102     public String getUserName() {
    103         return userName;
    104     }
    105 
    106     public void setUserName(String userName) {
    107         this.userName = userName;
    108     }
    109 
    110     public String getPassWord() {
    111         return passWord;
    112     }
    113 
    114     public void setPassWord(String passWord) {
    115         this.passWord = passWord;
    116     }
    117 
    118     public int getAge() {
    119         return age;
    120     }
    121 
    122     public void setAge(int age) {
    123         this.age = age;
    124     }
    125 }
    126 
    127  
    128 /**
    129  * 
    130  */
    131 package com.demo.ann.anns;
    132 
    133 import java.lang.annotation.ElementType;
    134 import java.lang.annotation.Retention;
    135 import java.lang.annotation.RetentionPolicy;
    136 import java.lang.annotation.Target;
    137 
    138 /**
    139  * ClassName:Column.java
    140  * @author xg.qiu
    141  * @since JDK1.7
    142  * Aug 3, 2015
    143  * 自定义注解:列
    144  * 用法:
    145  *         @Column("userId")
    146  *         private int userId;
    147  */
    148 @Target( ElementType.FIELD)//作用于属性
    149 @Retention( RetentionPolicy.RUNTIME)//有效期为运行时
    150 public @interface Column {
    151     String value();
    152 }
    153  
    154 
    155 
    156 
    157 
    158 /**
    159  
    160  * 
    161  */
    162 package com.demo.ann;
    163 
    164 import java.lang.reflect.Field;
    165 import java.lang.reflect.Method;
    166 
    167 import com.demo.ann.anns.Column;
    168 import com.demo.ann.anns.Table;
    169 import com.demo.ann.exception.AnnException;
    170 
    171 /**
    172    解析注解并返回执行的sql语句 
    173  * ClassName:Test.java
    174  * @author xg.qiu
    175  * @since JDK1.7
    176  * Aug 3, 2015
    177  * 测试:使用自定义注解完成数据库的查询返回sql语句
    178  *         1.根据id查询
    179  *         2.根据用户名查询
    180  *         3.根据用户名、密码组合查询
    181  */
    182 public class Test {
    183     public static void main(String[] args) {
    184         User user1 = new User();
    185         user1.setUserId(1);//根据Id查询
    186         
    187         User user2 = new User();
    188         user2.setUserName("xiaoqiu");// 根据用户名查询
    189         
    190         User user3 = new User();
    191         user3.setUserName("xiaoqiu");
    192         user3.setPassWord("123456");// 根据用户名、密码组合查询
    193         
    194         User user4 = new User();
    195         user4.setUserName("xiaoqiu,zasang,lisi");
    196         
    197         String sql1 = executeQuery(user1);
    198         String sql2 = executeQuery(user2);
    199         String sql3 = executeQuery(user3);
    200         String sql4 = executeQuery(user4);
    201         
    202         System.out.println(sql1);
    203         System.out.println(sql2);
    204         System.out.println(sql3);
    205         System.out.println(sql4);
    206         
    207     }
    208          /**
    209           * @param user 用户对象
    210           *@return String 返回的是拼装好的sql语句
    211           */
    212     private static String executeQuery(User user) {
    213         StringBuffer sb = new StringBuffer("select * from ");
    214         //1、获取类
    215         Class<? extends User> c = user.getClass();
    216         //2、查找类是否被注解
    217         boolean isExist = c.isAnnotationPresent(Table.class);
    218         if(!isExist){
    219             try {
    220                                 // 自定义异常
    221                 throw new AnnException("the "+ c.getClass().getName() +" class is not used annotation");
    222             } catch (AnnException e) {
    223                 e.printStackTrace();
    224             }
    225         }
    226                 // 获取Table注解 
    227         Table table = (Table) c.getAnnotation(Table.class);
    228         sb.append( table.value() +" where 1= 1");
    229         //3、查找属性是否被注解
    230         Field[] fields = c.getDeclaredFields();
    231         for(Field f : fields){
    232             //3.1、处理每个字段对应的sql
    233             //3.2、拿到字段值
    234             boolean isFExist = f.isAnnotationPresent(Column.class);
    235             if(!isFExist){
    236                 try {
    237                     throw new AnnException("the " + f.getName()  +" field is not used annotation");
    238                 } catch (AnnException e) {
    239                     e.printStackTrace();
    240                 }
    241             }
    242                         // 获取列注解 
    243             Column column = f.getAnnotation(Column.class);
    244             String columnName = column.value();
    245             //3.2、获取字段
    246             String fieldName = f.getName();
    247             //3.4、.拿到字段值
    248             Object values = null;
    249             String getFieldMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    250             try {
    251                 Method getMethod = c.getDeclaredMethod(getFieldMethodName);
    252                 values = getMethod.invoke(user);
    253                 //3.5.拼装sql
    254                 if( values == null || ( values instanceof Integer && (Integer) values == 0) ){
    255                     continue;
    256                 }
    257                 sb.append(" and ").append(columnName);
    258                 if(values instanceof Integer){
    259                     sb.append("=").append(values);
    260                 }else if(values instanceof String){
    261                     if( ((String) values).contains(",")){
    262                         String [] valuesIn = ((String) values).split(",");
    263                         sb.append(" in('");
    264                         for(String s : valuesIn){
    265                             sb.append(s).append("'").append(",");
    266                         }
    267                         sb.deleteCharAt(sb.length() - 1);
    268                         sb.append(")");
    269                     }else{
    270                         sb.append("='").append(values).append("'");
    271                     }
    272                 }
    273             } catch (Exception e) {
    274                                  // 打印堆栈信息 
    275                 e.printStackTrace();
    276             }
    277         }
    278                 // 返回拼装好的sql语句 
    279         return sb.toString();
    280     }
    281 }

    运行效果:
     
    select * from TABLE_USER where 1= 1 and USER_ID=1
    select * from TABLE_USER where 1= 1 and USER_NAME='xiaoqiu'
    select * from TABLE_USER where 1= 1 and USER_NAME='xiaoqiu' and PASS_WORD='123456'
    select * from TABLE_USER where 1= 1 and USER_NAME in('xiaoqiu',zasang',lisi')
  • 相关阅读:
    OD 实验(十三)
    第一个 Windows 界面程序
    C 语言
    C 语言
    OD 实验(十二)
    PowerShell 常用命令
    OD 实验(十一)
    OD 实验(十)
    redis
    memcached缓存系统
  • 原文地址:https://www.cnblogs.com/XQiu/p/5087849.html
Copyright © 2020-2023  润新知