当前位置: 首页 > news >正文

java反射查询数据库_java反射与注解结合使用(根据传入对象输出查询sql)

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

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

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

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

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

importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)public @interfaceTable {

String value();

}

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

importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;

@Target({ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)public @interfaceColumn {

String value();

}

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

/*** 数据库 user表,对应表字段为 userid/username/age/addredd*/@Table("user")public classUser {

@Column("userid")privateString userid;

@Column("username")privateString username;

@Column("age")private intage;

@Column("sl")private doublesl;

@Column("address")privateString address;//添加一个不是数据库的字段: 用于测试

privateString noField;public doublegetSl() {returnsl;

}public void setSl(doublesl) {this.sl =sl;

}publicString getNoField() {returnnoField;

}public voidsetNoField(String noField) {this.noField =noField;

}publicString getUserid() {returnuserid;

}public voidsetUserid(String userid) {this.userid =userid;

}publicString getUsername() {returnusername;

}public voidsetUsername(String username) {this.username =username;

}public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}publicString getAddress() {returnaddress;

}public voidsetAddress(String address) {this.address =address;

}

}

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

importjava.lang.annotation.Annotation;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.Objects;/*** 注解*/

public classAnnotationUtil {/*** 根据传入的对象 来生成query sql

*

*@paramobject

*@return

*/

public static String getSqlByAnnotation(Object object) throwsException {//使用StringBuilder 线程安全

StringBuilder sb = newStringBuilder();//检查参数是否为空

Objects.requireNonNull(object, "该对象不能为空!");//1.通过反射获取该对象的类类型

Class c =object.getClass();//2.获取该对象的 类注解: 标明表名

boolean table_flag = c.isAnnotationPresent(Table.class);if (!table_flag) {throw newNullPointerException();

}

Table table= (Table) c.getDeclaredAnnotation(Table.class);

sb.append("SELECT * FROM ").append(table.value()).append(" WHERE 1 = 1");//3.获取该对象的 字段注解:显示查询字段

Field[] fields =c.getDeclaredFields();booleanfield_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);

}

}returnsb.toString();

}public static voidmain(String[] args) {

User user= newUser();

user.setUserid("0001");

user.setAge(23);//用于测试没有带Column注解的字段

user.setNoField("field");try{

System.out.println(AnnotationUtil.getSqlByAnnotation(user));

}catch(Exception e) {

e.printStackTrace();

}

}

}

相关文章:

  • Java 类Servletrequest_java中servlet中有关HttpServletRequest的不理解
  • java 值 继承_java中的继承
  • java 颜色条_具有多个颜色条的子图
  • java 图片数据管理_Java实现图片内容无损任意角度旋转
  • java流量监控系统demo_搭建一个简单的基于web的网络流量监控可视化系统
  • jquery与java_纯javascript和jquery实现增删改查
  • mysql 批量字段前缀_sqlserver数据库,批量更改表名和字段的前缀 | 学步园
  • pdfpcell 怎么设置单元格大小_PdfPCell的方法隐藏单元格的边框
  • java strace_用strace排查故障的5种简单方法(每日一译)
  • java银行账户系统_用java编的银行账户系统代码
  • java扩展包_CodeRunner 的 Java 扩展 Jar 包支持
  • java session 修改_修改 Servlet 的sessionId
  • qt添加qwt帮助文件_win 7下安装qwt 6.1.0,基于qt 4.8.5
  • java亮眼_一些java处理变量的 让我眼前一亮的
  • 36岁自学python_深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Android 架构优化~MVP 架构改造
  • LeetCode18.四数之和 JavaScript
  • node学习系列之简单文件上传
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Vim Clutch | 面向脚踏板编程……
  • 分布式事物理论与实践
  • 给github项目添加CI badge
  • 解析带emoji和链接的聊天系统消息
  • 设计模式走一遍---观察者模式
  • 使用Swoole加速Laravel(正式环境中)
  • linux 淘宝开源监控工具tsar
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • # 数论-逆元
  • #stm32驱动外设模块总结w5500模块
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (4.10~4.16)
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (算法)求1到1亿间的质数或素数
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (转载)Linux网络编程入门
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • .Mobi域名介绍
  • .Net 6.0 处理跨域的方式
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .Net Core 中间件验签
  • .net MySql
  • .NET Project Open Day(2011.11.13)
  • .Net 代码性能 - (1)
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET6实现破解Modbus poll点表配置文件
  • .net下简单快捷的数值高低位切换
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @Autowired 与@Resource的区别
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛