使用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')
原文地址:https://www.cnblogs.com/XQiu/p/5087849.html