使用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‘)
时间: 2024-08-09 19:53:55

使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句的相关文章

Java反射与自定义注解

反射,在Java常用框架中屡见不鲜.它存在于java.lang.reflact包中,就我的认识,它可以拿到类的字段和方法,及构造方法,还可以生成对象实例等.对深入的机制我暂时还不了解,本篇文章着重在使用方面,并附上一个本人应用到项目中的案例. 基础姿势 拿到类,反射是以类为基础的基础,首先拿到项目中的类,既可以这样拿 Class<?> clazz = Class.forName(类路径); 也可以这样拿 Class<?> clazz = 类名.getClass(); 在一般意义的J

C#反射生成简单sql语句

static void Main(string[] args) { book book = new book();//实体类 booktest b1 = new booktest(); book.bookid = "1"; book.bookname = "计算机原理"; book.bookprice = 32.04M; string sql = CreateInsertSQL(book); } public static string CreateInsertSQ

Java反射reflection与注解annotation的应用(自动测试机)

一.关于自动测试机 1.什么是自动测试机? 对类中的指定方法进行批量测试的工具 2.自动测试机又什么用? a.避免了冗长的测试代码 当类中的成员方法很多时,对应的测试代码可能会很长,使用测试能够让测试代码非常简洁 b.降低了类与测试代码之间的耦合性 以防万一,测试时应该对类中所有方法进行测试.当我们对类中的一个方法做改动时,很可能我们的测试代码也要做相应改动(如改变了方法名,返回值类型等等),使用测试机能降低类与测试代码之间的耦合性,大大降低不必要的工作量. c.增加了测试的灵活性 测试类与待测

一小时搞明白自定义注解(Annotation)

原文链接:http://blog.csdn.net/u013045971/article/details/53433874 什么是注解 Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法.Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据. Annotation(注解)是JDK5.0及以后版本引入的.它可以用于创建文档,跟踪代码中的

springmvc之自定义注解(annotation)

参考:日志处理 三:Filter+自定义注解实现 系统日志跟踪功能 1.项目结构 2.pom.xml,添加需要依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://mav

JUnit 4 使用 Java 5 中的注解(annotation)

JUnit 4 使用 Java 5 中的注解(annotation),以下是JUnit 4 常用的几个 annotation 介绍@Before:初始化方法@After:释放资源@Test:测试方法,在这里可以测试期望异常和超时时间@Ignore:忽略的测试方法@BeforeClass:针对所有测试,只执行一次,且必须为static void@AfterClass:针对所有测试,只执行一次,且必须为static void一个JUnit 4 的单元测试用例执行顺序为:@BeforeClass –>

通过反射,获得数据库增删改查的sql语句的方法

package gxa.bj.util; import java.lang.reflect.*; public class BeanUtil {// 根据某些条件查询语句 public static String getSelectSQL(Object obj) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetExc

Java反射学习总结五(Annotation(注解)-基础篇)

Annotation(注解)简单介绍: 注解大家印象最深刻的可能就是JUnit做单元測试,和各种框架里的使用了. 本文主要简介一下注解的用法,下篇文章再深入的研究. annotation并不直接影响代码语义.可是它可以被看作类似程序的工具或者类库.它会反过来对正在执行的程序语义有所影响. annotation能够从源文件,class文件或者以在执行时反射的多种方式被读取 java注解系统自带有主要下面几个注解: Override注解表示子类要重写(override)父类的相应方法 Depreca

Java:自定义注解(Annotation)

在网上找了很多资料也有写的比较好的,但是总有有一点半点的细节没有写出来,在这里自己总结下使用. 使用Java的自定义注解,首先个人需要了解下Java为我们提供的元注解和相关定义注解的语法.(这个我在网上选择了一篇详细的介绍链接在文章最底层) 1.首先自定义我们需要的注解 package com.plat; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lan