使用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')

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

  1. Java学习笔记之--------注解(Annotation)

    注解的定义 注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等 ...

  2. 通过反射获得自定义注解的值

    通过反射获得自定义注解的值 1.简介 ​ 自动JDK5之后,注解逐渐进入了大众的视野,注解对程序的完成有很好的辅助作用,极大的简化了开发步骤与操作,那么如何定义一个注解,以及注解是如何生效的呢. ​ ...

  3. 浅谈Java反射(Reflect)技术--常用方法

    Java反射(Reflect)技术 概念:动态获取在当前Java虚拟机中的类.接口或者对象等等信息(运行过程中读取内容) 1.作用(面试问题): 1.1 解除两个类之间的耦合性,即在未得到依赖类的情况 ...

  4. java反射实现自定义json转对象方法-忽略字段大小写、字段个数

    java反射实现自定义json转对象方法-忽略字段大小写.字段个数 开发过程中经常会遇到json转对象,可以使用FastJson或者Gson自带的工具类进行转换,但当遇到json与对象属性名称大小写不 ...

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

    Annotation(注解)简单介绍: 注解大家印象最深刻的可能就是JUnit做单元測试,和各种框架里的使用了. 本文主要简介一下注解的用法,下篇文章再深入的研究. annotation并不直接影响代 ...

  6. 实现基于注解(Annotation)的数据库框架(三)自定义注解(Annotation)

    #前言# 之前已经简单介绍了系统的内置注解,我们已经对注解有了一个初步的印象,接下来就来看看如何自定义注解. 此文章仍然转载自上一篇的作者,因为他写的实在是太好了,非常适合刚接触注解的朋友去看,原文的 ...

  7. 88 java反射_4 _注解

    文章目录 枚举 枚举的本质 枚举与Switch配合使用 注解 定义注解 注解属性类型 注解的本质 反射获取注解信息 元注解 枚举 什么是枚举: 枚举是一个引用类型,枚举是一个规定了取值范围的数据类型. ...

  8. java 切片_JAVA自定义注解并切片应用

    Java支持注解形式,合理使用注解,可以对我们的编程提供极大的便利.JAVA自身提供了三种注解,分别是:@Override,@Deprecated,@SuppreWarnings.大家平时应该看见这个 ...

  9. Java反射机制与注解

    Java反射机制 反射机制是java的动态机制,可以在程序"运行期间"再确定实例化对象,方法调用,属性操作等. 反射机制可以提高代码的灵活度,但是会带来较多的系统开销和较低的运行效 ...

最新文章

  1. php开发我的世界插件,WorldEdit/开发与API
  2. oc-29-可变数组
  3. 解决JQuery AutoComplete在IE9下出错的问题
  4. C++判断一个数字是否是某个数字的阶乘(附完整源码)
  5. 【泰语歌】กลับคำสาหล่า 歌手:Mike Piromporn
  6. PHP中使用八进制 可以在前面加,PHP学习笔记(二)
  7. 凯撒密码加密算法python_Python最新暴力破解WiFi,攻破所有密码限制,最强破解!...
  8. ssis导入xml_SSIS包中的XML任务概述
  9. Web---session技术代码演示(request,session,servletContext)
  10. 微信小程序云开发教程-微信小程序的JSON配置
  11. 禁止选择,右键菜单,拷贝,拖拽
  12. C语言数据结构与算法 项目实战 教学视频(完整)
  13. gg修改器修改数值没有用怎么办_GG修改器详细使用教程
  14. SWUST大二周赛 之农夫山泉有点甜
  15. 如何预防 XSS 攻击
  16. 使用3DMAX制作一枚手雷
  17. 大平台压榨亏损2000万怎么办?换流量变现策略才是王道!
  18. Ubuntu搭建团队文档协作在线平台
  19. iOS启动速度优化实践分享
  20. Java实现的一个简单聊天软件

热门文章

  1. R读取MySQL数据出现乱码,解决该问题的方法总结
  2. VMware虚拟机CentOS7 - VMnet8网络配置及常见问题解决
  3. canvas生成图片toDataURL报错的原因和解决方法
  4. nginx实现动态分离,解决css和js等图片加载问题
  5. Windows10 解决“装了 .NET Framework 4.5.2/4.6.1/4.7.1等等任何版本 或版本更高的更新”问题
  6. 如何在移动网页上“禁用”缩放?
  7. 如何强制gradle重新下载依赖项?
  8. 如何将字节数组转换为十六进制字符串,反之亦然?
  9. win11组策略如何恢复默认设置 windows11组策略恢复默认设置的步骤方法
  10. 如何修复Win11上的时钟不同步?Win11时钟不同步修复方法