本文共 6047 字,大约阅读时间需要 20 分钟。
使用Java反射(Reflect)、自定义注解(Customer An notation)生成简单SQL语句 这次给大家介绍一下在Java开发过程中 使用自定义注解开发: 主要知识点: 1.反射 主要用于提取注解信息 2.自定义异常 主要是为了自己自定义一个异常信息 3.自定义注解 本次重点 学会如何自定义注解以及如何使用反射提取注解信息运用到实际开发 下图表示在Java中注解的含义以及注解的分类和如何解析注解 通常我们使用自定义注解一般使用4中元注解即:@Target@Retention@Documented @Inherited * ClassName:package-info.java * @Target :用于描述注解的使用范围(即:被描述的注解可以用在什么地方) 1.ElementType.CONSTRUCTOR:用于描述构造器 2.ElementType.FIELD:用于描述域 3.ElementType.LOCAL_VARIABLE:用于描述局部变量 4.ElementType.METHOD:用于描述方法 5.ElementType.PACKAGE:用于描述包 6.ElementType.PARAMETER:用于描述参数 7.ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明 @Retention :@Retention定义了该Annotation被保留的时间长短 1.RetentionPolicy.SOURCE:在源文件中有效(即源文件保留) 2.RetentionPolicy.CLASS:在class文件中有效(即class保留) 3.RetentionPolicy.RUNTIME:在运行时有效(即运行时保留) @Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API, @Inherited :元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的 [必须是extend class 而不是implements interface] 注解语法: public @interface 注解名{ // 注解变量 // 元数据类型:基本数据类型 String class enum Annotation 以及上述类型数组 // 如果元数据只有一个时 必须声明为value(); } /** package com.demo.ann.anns; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target( ElementType.TYPE)// 作用域 类或接口 @Retention( RetentionPolicy.RUNTIME)// 有效期为运行时 public @interface Table { import com.demo.ann.anns.Column; import com.demo.ann.anns.Table; * @since JDK1.7 Aug 3, 2015 public void setUserId(int userId) { public String getUserName() { public void setUserName(String userName) { this.userName = userName; public String getPassWord() { public void setPassWord(String passWord) { this.passWord = passWord; public void setAge(int age) { package com.demo.ann.anns; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target( ElementType.FIELD)//作用于属性 @Retention( RetentionPolicy.RUNTIME)//有效期为运行时 public @interface Column { /** import java.lang.reflect.Field; import java.lang.reflect.Method; import com.demo.ann.anns.Column; import com.demo.ann.anns.Table; import com.demo.ann.exception.AnnException; * 测试:使用自定义注解完成数据库的查询返回sql语句 public static void main(String[] args) { user1.setUserId(1);//根据Id查询 user2.setUserName("xiaoqiu");// 根据用户名查询 user3.setUserName("xiaoqiu"); user3.setPassWord("123456");// 根据用户名、密码组合查询 user4.setUserName("xiaoqiu,zasang,lisi"); String sql1 = executeQuery(user1); String sql2 = executeQuery(user2); String sql3 = executeQuery(user3); String sql4 = executeQuery(user4); System.out.println(sql1); System.out.println(sql2); System.out.println(sql3); System.out.println(sql4); } * @param user 用户对象 *@return String 返回的是拼装好的sql语句 private static String executeQuery(User user) { StringBuffer sb = new StringBuffer("select * from "); Class<? extends User> c = user.getClass(); boolean isExist = c.isAnnotationPresent(Table.class); throw new AnnException("the "+ c.getClass().getName() +" class is not used annotation"); } catch (AnnException e) { Table table = (Table) c.getAnnotation(Table.class); sb.append( table.value() +" where 1= 1"); Field[] fields = c.getDeclaredFields(); boolean isFExist = f.isAnnotationPresent(Column.class); throw new AnnException("the " + f.getName() +" field is not used annotation"); } catch (AnnException e) { Column column = f.getAnnotation(Column.class); String columnName = column.value(); String fieldName = f.getName(); String getFieldMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method getMethod = c.getDeclaredMethod(getFieldMethodName); values = getMethod.invoke(user); if( values == null || ( values instanceof Integer && (Integer) values == 0) ){ sb.append(" and ").append(columnName); if(values instanceof Integer){ sb.append("=").append(values); }else if(values instanceof String){ if( ((String) values).contains(",")){ String [] valuesIn = ((String) values).split(","); for(String s : valuesIn){ sb.append(s).append("'").append(","); sb.deleteCharAt(sb.length() - 1); sb.append("='").append(values).append("'"); } catch (Exception e) { // 打印堆栈信息 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') 转载地址:http://mlwno.baihongyu.com/