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

简介:

使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单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')

目录
相关文章
|
26天前
|
Java
让星星⭐月亮告诉你,自定义定时器和Java自带原生定时器
定时器是一种可以设置多个具有不同执行时间和间隔的任务的工具。本文介绍了定时器的基本概念、如何自定义实现一个定时器,以及Java原生定时器的使用方法,包括定义定时任务接口、实现任务、定义任务处理线程和使用Java的`Timer`与`TimerTask`类来管理和执行定时任务。
43 3
|
5天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
15天前
|
SQL 数据库 开发者
功能发布-自定义SQL查询
本期主要为大家介绍ClkLog九月上线的新功能-自定义SQL查询。
|
15天前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
11 0
[Java]反射
|
20天前
|
安全 Java
如何在 Java 中创建自定义安全管理器
在Java中创建自定义安全管理器需要继承SecurityManager类并重写其方法,以实现特定的安全策略。通过设置系统安全属性来启用自定义安全管理器,从而控制应用程序的访问权限和安全行为。
|
1月前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
56 2
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
|
2月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
60 9
Java——反射&枚举
|
26天前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
23 2
|
1月前
|
消息中间件 存储 Java
大数据-58 Kafka 高级特性 消息发送02-自定义序列化器、自定义分区器 Java代码实现
大数据-58 Kafka 高级特性 消息发送02-自定义序列化器、自定义分区器 Java代码实现
41 3
|
24天前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
15 0