博客已迁移到CSDN《https://blog.csdn.net/qq_33375499

  我们在项目开发中有很多地方使用到了注解,关于注解的定义与创建小伙伴可以参考我的文章《java注解》。有任何问题的小伙伴们可以在评论区指出哦,欢迎各位大佬指出问题。

  今天我要说的是使用注解与反射结合使用,来使我们代码根据优雅,更加高大上(咳,装逼神器啊)。

  注解使用@interface 来定义,辣么我们自定义的注解,该使用获取到并且指明该注解的作用呢?java提供了反射机制,通过类的类类型我们可以根据自己需要老操作该类。有管反射的知识,可以参考我的上两章博客。好了,废话不多说,我们上代码:

 需求:创建一个与数据库表对应的实体类,通过使用注解的方式,来生成该实体类的查询sql语句。

  1.创建Table类注解,用于标明该类对应数据库的表名称

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 {
String value();
}

  2.创建Column字段注解,用于标明该类中属性与数据库表字段的映射

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 {
String value();
}

  3.创建实体类,并使用注解Table、Column

/**
* 数据库 user表,对应表字段为 userid/username/age/addredd
*/
@Table("user")
public class User {
@Column("userid")
private String userid;
@Column("username")
private String username;
@Column("age")
private int age;
@Column("sl")
private double sl;
@Column("address")
private String address;
// 添加一个不是数据库的字段: 用于测试
private String noField; public double getSl() {
return sl;
} public void setSl(double sl) {
this.sl = sl;
} public String getNoField() {
return noField;
} public void setNoField(String noField) {
this.noField = noField;
} public String getUserid() {
return userid;
} public void setUserid(String userid) {
this.userid = userid;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
}
}

  4.创建工具类,根据传入该对象,来生成对应的查询sql

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects; /**
* 注解
*/
public class AnnotationUtil {
/**
* 根据传入的对象 来生成query sql
*
* @param object
* @return
*/
public static String getSqlByAnnotation(Object object) throws Exception {
// 使用StringBuilder 线程安全
StringBuilder sb = new StringBuilder();
// 检查参数是否为空
Objects.requireNonNull(object, "该对象不能为空!");
// 1.通过反射获取该对象的类类型
Class c = object.getClass();
// 2.获取该对象的 类注解: 标明表名
boolean table_flag = c.isAnnotationPresent(Table.class);
if (!table_flag) {
throw new NullPointerException();
}
Table table = (Table) c.getDeclaredAnnotation(Table.class);
sb.append("SELECT * FROM ").append(table.value()).append(" WHERE 1 = 1");
// 3.获取该对象的 字段注解:显示查询字段
Field[] fields = c.getDeclaredFields();
boolean field_flag;
Column column;
String field_name;
Method menthod;
Object val;
for (Field field : fields) {
// 首先得拿到字段名称:通过字段上的注解标明该指定是数据库表对应的字段
field_flag = field.isAnnotationPresent(Column.class);
if (!field_flag) {
continue;
}
column = field.getDeclaredAnnotation(Column.class);
// 其次得拿到字段值 : 通过反射调用类的getXxxx方法
field_name = field.getName();
menthod = c.getDeclaredMethod("get" + Character.toUpperCase(field_name.charAt(0)) + field_name.substring(1));
val = menthod.invoke(object);
// 判断该字段是否为空,不为空,才进行append
// 这里要注意:有些属性不赋值时候,java会自动生成默认值,如Double默认为0.0
// 还有其他类型,小伙伴们可以自行测试
if (!Objects.isNull(val)) {
if((val instanceof Double) && (double) val == 0.0){
continue;
}
sb.append(" AND ").append(column.value()).append(" = ");
sb.append(val);
}
}
return sb.toString();
} public static void main(String[] args) {
User user = new User();
user.setUserid("0001");
user.setAge(23);
// 用于测试没有带Column注解的字段
user.setNoField("field");
try {
System.out.println(AnnotationUtil.getSqlByAnnotation(user));
} catch (Exception e) {
e.printStackTrace();
}
}
}

java反射与注解结合使用(根据传入对象输出查询sql)的更多相关文章

  1. Java反射,注解,以及动态代理

    Java反射,注解,以及动态代理 基础  最近在准备实习面试,被学长问到了Java反射,注解和动态代理的内容,发现有点自己有点懵,这几天查了很多资料,就来说下自己的理解吧[如有错误,望指正] Java ...

  2. 利用反射跟自定义注解拼接实体对象的查询SQL

    前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...

  3. JavaSE学习总结(十五)—— Java反射与注解

    一.静态语言与动态语言 静态类型语言:是指在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型,某些具有类型推导能力的现代语言可能能够部分减轻这个要求.强类型 动态 ...

  4. Java反射及注解

    一.反射 1.动态语言:是指程序在运行是可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见的JavaScript就是动态语言,除此以外Python等也属于动态语言,而C.C ...

  5. java 反射,注解,泛型,内省(高级知识点)

     Java反射 1.Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs    取得任何一个已知名称的class的内部信息, 包括 ...

  6. java反射获取注解并拼接sql语句

    先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...

  7. 【转】JAVA反射与注解

    转载自:https://www.daidingkang.cc/2017/07/18/java-reflection-annotations/ 前言 现在在我们构建自己或公司的项目中,或多或少都会依赖几 ...

  8. JAVA反射机制_获取字节码文件对象

    是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...

  9. Java 反射、注解

    1. 泛型 基本用法.泛型擦除.泛型类/泛型方法/泛型接口.泛型关键字.反射泛型! a. 概述 泛型是JDK1.5以后才有的, 可以在编译时期进行类型检查,且可以避免频繁类型转化! // 运行时期异常 ...

随机推荐

  1. git ---回到过去

    git命令回顾 git checkout /git reset -git reset HEAD~    //~代表回滚到第几个版本.. 有多个的话可以在~后面加个数字 git reset --mixe ...

  2. numpy基本用法

    numpy 简介 numpy的存在使得python拥有强大的矩阵计算能力,不亚于matlab. 官方文档(https://docs.scipy.org/doc/numpy-dev/user/quick ...

  3. C++ class、struct区别

    一.默认访问控制不同(最主要) struct默认为public,class默认为private.这个访问控制既是指成员的默认访问属性,又指继承时默认的继承属性. 二.定义template时不同 在模版 ...

  4. CAD参数绘制线型标注(com接口)

    主要用到函数说明: _DMxDrawX::DrawDimRotated 绘制一个线型标注.详细说明如下: 参数 说明 DOUBLE dExtLine1PointX 输入第一条界线的起始点X值 DOUB ...

  5. vc++实现控制USB设备启用与否

    #include <WINDOWS.H>      #include <TCHAR.H>      #include <SETUPAPI.H>      //#in ...

  6. What is state and props

    State, in React component, is internal dataset which affects the rendering of the component. To some ...

  7. Java中List集合的遍历

    一.对List的遍历有三种方式 List<String> list = new ArrayList<String>(); list.add("testone" ...

  8. 【C语言】控制台窗口图形界面编程(七):鼠标事件

    目录 00. 目录 01. INPUT_RECORD结构 02. MOUSE_EVENT_RECORD结构 03. ReadConsoleInput函数 04. 示例程序 00. 目录 01. INP ...

  9. git命令初级

    git是开源的分布式版本控制系统,分布式主要区别于集中式代表CVS(Concurrent Version System,遵从C/S架构,同步比较笨拙.)和SVN(Subversion),linux开发 ...

  10. 利用WITH AS改写SQL

    报表程序中一段SQL语句. 优化前: 返回:3952 耗时:224s SQL 代码: select to_date(nvl(pro.value, '1900-01-01 00:00:00'), 'YY ...