java反射与注解结合使用(根据传入对象输出查询sql)
博客已迁移到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)的更多相关文章
- Java反射,注解,以及动态代理
Java反射,注解,以及动态代理 基础 最近在准备实习面试,被学长问到了Java反射,注解和动态代理的内容,发现有点自己有点懵,这几天查了很多资料,就来说下自己的理解吧[如有错误,望指正] Java ...
- 利用反射跟自定义注解拼接实体对象的查询SQL
前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...
- JavaSE学习总结(十五)—— Java反射与注解
一.静态语言与动态语言 静态类型语言:是指在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型,某些具有类型推导能力的现代语言可能能够部分减轻这个要求.强类型 动态 ...
- Java反射及注解
一.反射 1.动态语言:是指程序在运行是可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见的JavaScript就是动态语言,除此以外Python等也属于动态语言,而C.C ...
- java 反射,注解,泛型,内省(高级知识点)
Java反射 1.Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs 取得任何一个已知名称的class的内部信息, 包括 ...
- java反射获取注解并拼接sql语句
先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...
- 【转】JAVA反射与注解
转载自:https://www.daidingkang.cc/2017/07/18/java-reflection-annotations/ 前言 现在在我们构建自己或公司的项目中,或多或少都会依赖几 ...
- JAVA反射机制_获取字节码文件对象
是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...
- Java 反射、注解
1. 泛型 基本用法.泛型擦除.泛型类/泛型方法/泛型接口.泛型关键字.反射泛型! a. 概述 泛型是JDK1.5以后才有的, 可以在编译时期进行类型检查,且可以避免频繁类型转化! // 运行时期异常 ...
随机推荐
- JavaScript实现JQuery的功能
- Oracle数据库的SQL语句之完整性约束——基础篇
SELECT * FROM tb_clazz;SELECT * FROM tb_student; INSERT INTO tb_clazz(code,NAME,bzr) VALUES('1401',' ...
- QPushButton注册事件过滤器后按钮消失
版权声明:本文为博主原创文章,转载需要注明出处. RT,代码如下: ui.btn_set->installEventFilter(this); bool MousrHoverTest::even ...
- java web 学习笔记 - tomcat数据源
1. 数据库源 以前的JDBC连接步骤为: 1.加载数据库驱动 2.通过DriverManger获取数据库连接connection 3.通过connection执行prepareStatement的响 ...
- java规范与标准?
所谓规范,即指由很多人同时遵守的行为或理论. java的规范并不是指其中一种,而是有很多种,比如java编码规范,java命名规范,java虚拟机规范等等,甚至于一个编码规范都有很多种,不同的公司.组 ...
- swift -Dynamic Dispatch
These instructions perform dynamic lookup of class and generic methods. The class_method and super_m ...
- 使用Caliburn.Micro系列2:Convention
CM中实现一个比较有意思的特性,就是智能匹配. 通常使用MVVM的写法:在匹配 View和ViewModel时会使用DataContext,在匹配数据属性时使用Binding,在匹配事件命令时使用Co ...
- 第2节 mapreduce深入学习:7、MapReduce的规约过程combiner
第2节 mapreduce深入学习:7.MapReduce的规约过程combiner 每一个 map 都可能会产生大量的本地输出,Combiner 的作用就是对 map 端的输出先做一次合并,以减少在 ...
- 阿里云报错Redirecting to /bin/systemctl restart sshd.service
转:http://blog.csdn.net/caijunfen/article/details/70599138 云服务器 ECS Linux CentOS 7 下重启服务不再通过 service ...
- pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法
squeeze的用法主要就是对数据的维度进行压缩或者解压. 先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的 ...