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以后才有的, 可以在编译时期进行类型检查,且可以避免频繁类型转化! // 运行时期异常 ...
随机推荐
- LN : leetcode 343 Integer Break
lc 343 Integer Break 343 Integer Break Given a positive integer n, break it into the sum of at least ...
- hihocoder编程练习赛52-3 部门聚会
思路: 树形dp. 实现: #include <bits/stdc++.h> using namespace std; ; int n, a[MAXN], in[MAXN]; vector ...
- swiper4实现的拥有header和footer的全屏滚动demo/swiper fullpage footer
用swiper4实现的拥有header和footer的全屏滚动demo, <!DOCTYPE html> <html lang="en"> <head ...
- CCF|跳一跳
import java.util.Scanner; public class Main { public static void main (String[] args) { Scanner scan ...
- 图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用
图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用 传输层必须指出这个具体的程序,为了实现这一功能,使用端口号这样一种识别码.根据端口号,就可以识别在传输层上一层的应用程 ...
- JVM 优点与缺点的深入分析
Java 最初诞生的时候,它可以说是其他语言的进化版.不仅因为Java很简单,而且这一进化的语言还是一个可以运行第三方硬件字节码的虚拟机.它还是垃圾收集站,从而令存储管理和内核转储(core dump ...
- PC端浏览器定位
第一: PC端浏览器定位(纯前端)浏览器定位 :这里用了两种 ,一种是Html5自带的方法 另一种是引用了百度api ,百度api 的使用有三种:1 浏览器定位2 ip定位3 SDK辅助定位引用百度 ...
- Oracle使用plsql连不上本地数据库,cmd中使用sqlplus连的上的可能解决方案
1.无监听程序 原因: 最有可能是oracle监听的服务没有启动起来. 2.ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 原因: 1.服务没有配置127.0.0.1或监听程序没 ...
- PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (四) -- Push API 和 Pull API
RabbitMQ 中针对消息的分发提供了 Push API (订阅模式) 和 Pull API (主动获取) 两种模式. 在 PHP 中, 这两种模式分别通过 AMQPQueue 类中的 consum ...
- 梦回----32位CPU和64位CPU的通用寄存器
1 32位Intel的CPU通用寄存器 32位CPU所含有的寄存器有:4个数据寄存器(EAX.EBX.ECX和EDX):2个变址和指针寄存器(ESI和EDI):2个指针寄存器(ESP和EBP):6个段 ...