博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句
阅读量:6576 次
发布时间:2019-06-24

本文共 6047 字,大约阅读时间需要 20 分钟。

使用Java反射(Reflect)、自定义注解(Customer An
notation)生成简单SQL语句
这次给大家介绍一下在Java开发过程中 使用自定义注解开发:
主要知识点:
            1.反射            主要用于提取注解信息
            2.自定义异常  主要是为了自己自定义一个异常信息
            3.自定义注解  本次重点 学会如何自定义注解以及如何使用反射提取注解信息运用到实际开发
下图表示在Java中注解的含义以及注解的分类和如何解析注解
通常我们使用自定义注解一般使用4中元注解即:
@Target
@Retention
@Documented
@Inherited
/**
 * 
 */
/**
 * ClassName:package-info.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 使用自定义注解:
 * @Target :用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
 * 取值(ElementType)有:
    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被保留的时间长短
  取值(RetentionPoicy)有:
    1.RetentionPolicy.SOURCE:在源文件中有效(即源文件保留)
    2.RetentionPolicy.CLASS:在class文件中有效(即class保留)
    3.RetentionPolicy.RUNTIME:在运行时有效(即运行时保留)
  @Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,
   因此可以被例如javadoc此类的工具文档化。
   Documented是一个标识注解,没有成员。
  @Inherited :元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的
   [必须是extend class 而不是implements interface]
 */
package com.demo.ann;
注解语法:
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;
/**
 * ClassName:Table.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 自定义注解:表
 * 用法:
 *  @Table("user")
 *  public class User
 */
@Target( ElementType.TYPE)// 作用域 类或接口
@Retention( RetentionPolicy.RUNTIME)// 有效期为运行时
public @interface Table {
String value();
}
/**
 * 
 */
package com.demo.ann;
import com.demo.ann.anns.Column;
import com.demo.ann.anns.Table;
/**
 * ClassName:User.java
 * 
 * @author xg.qiu
 * @since JDK1.7 Aug 3, 2015
 */
@Table("TABLE_USER")
public class User {
@Column("USER_ID")
private int userId;
@Column("USER_NAME")
private String userName;
@Column("PASS_WORD")
private String passWord;
@Column("AGE")
private int age;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = 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;
/**
 * ClassName:Column.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 自定义注解:列
 * 用法:
 *  @Column("userId")
 *  private int userId;
 */
@Target( ElementType.FIELD)//作用于属性
@Retention( RetentionPolicy.RUNTIME)//有效期为运行时
public @interface Column {
String value();
}
 
/**
 
 * 
 */
package com.demo.ann;
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语句 
 * ClassName:Test.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 测试:使用自定义注解完成数据库的查询返回sql语句
 *  1.根据id查询
 *  2.根据用户名查询
 *  3.根据用户名、密码组合查询
 */
public class Test {
public static void main(String[] args) {
User user1 = new User();
user1.setUserId(1);//根据Id查询
User user2 = new User();
user2.setUserName("xiaoqiu");// 根据用户名查询
User user3 = new User();
user3.setUserName("xiaoqiu");
user3.setPassWord("123456");// 根据用户名、密码组合查询
User user4 = new User();
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 ");
//1、获取类
Class<? extends User> c = user.getClass();
//2、查找类是否被注解
boolean isExist = c.isAnnotationPresent(Table.class);
if(!isExist){
try {
                                // 自定义异常
throw new AnnException("the "+ c.getClass().getName() +" class is not used annotation");
} catch (AnnException e) {
e.printStackTrace();
}
}
                // 获取Table注解 
Table table = (Table) c.getAnnotation(Table.class);
sb.append( table.value() +" where 1= 1");
//3、查找属性是否被注解
Field[] fields = c.getDeclaredFields();
for(Field f : fields){
//3.1、处理每个字段对应的sql
//3.2、拿到字段值
boolean isFExist = f.isAnnotationPresent(Column.class);
if(!isFExist){
try {
throw new AnnException("the " + f.getName()  +" field is not used annotation");
} catch (AnnException e) {
e.printStackTrace();
}
}
                        // 获取列注解 
Column column = f.getAnnotation(Column.class);
String columnName = column.value();
//3.2、获取字段
String fieldName = f.getName();
//3.4、.拿到字段值
Object values = null;
String getFieldMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
try {
Method getMethod = c.getDeclaredMethod(getFieldMethodName);
values = getMethod.invoke(user);
//3.5.拼装sql
if( values == null || ( values instanceof Integer && (Integer) values == 0) ){
continue;
}
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(",");
sb.append(" in('");
for(String s : valuesIn){
sb.append(s).append("'").append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
}else{
sb.append("='").append(values).append("'");
}
}
} catch (Exception e) {
                                 // 打印堆栈信息 
e.printStackTrace();
}
}
                // 返回拼装好的sql语句 
return sb.toString();
}
}
运行效果:
 
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/

你可能感兴趣的文章
征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)
查看>>
[转载]触摸屏网站制作的小细节
查看>>
[转载]INNO Setup 使用笔记
查看>>
Servlet--HttpSession接口,HttpSessionContext接口,Cookie类
查看>>
Android世界第一个activity启动过程
查看>>
RR调度(Round-robin scheduling)简单介绍
查看>>
重载函数编译后的新名字
查看>>
oracle resetlog与noresetlog的作用(转载)
查看>>
linux服务器内存占用太高-释放内存
查看>>
Linux下长时间ping网络加时间戳并记录到文本(转)
查看>>
在Unity中实现屏幕空间反射Screen Space Reflection(2)
查看>>
目录的操作
查看>>
进程简述
查看>>
求height数组
查看>>
c语言中通过指针将数值赋值到制定内存地址
查看>>
Python学习—2048小游戏等4个小练习
查看>>
构造函数和构造代码块
查看>>
颠倒顺序了,
查看>>
局部加权线性回归,线性回归高级版
查看>>
约瑟夫问题(猴子选大王)
查看>>