news 2026/10/30 1:00:52

java 注解应用流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java 注解应用流程

Java注解,来自小白的疑惑

平时开发我们会经常会引入第三方库,比如数据库框架ormlite,retrofit, 用的时候必须要用注解来映射到属性上去。下面贴出两个注解使用的截图


本人也有很大一段时间对注解保持着仇恨的态度,一看到注解就发怵。但是又不能放弃,毕竟这东西主流的一些框架都在用。于是今天从一个小例子来学习一下这个新手又爱又恨的东西

我们就拿一个通过注解来生成sql语句的例子来分析吧(这个例子是我在别人博客里面看到的 原出处请点击,我只是拿我的话再说一遍:

首先我们都知道,数据库是怎么回事,需要表名,和字段名,我们想定义这俩东西需要用到的注解:

/** * 这个之前,我要先说这个注解的定义 * 写法是不是和类的定义很相似啊, @interface 就说明他是一个注解啦, * 再看第一行,@Target 这个就是要告诉用注解的人,我这个的作用范围, * 就这个例子来说 ElementType.TYPE 意思就是我这个注解你只能用来作用于类,而不能作用于变量或者方法上面 * 他的取值我们可以看一下 ElementType 这个enum里面的说明,一看就明白,不多说 * * 第二行这个 @Retention 是用来规定这个注解要作用的时机,RetentionPolicy.RUNTIME 就是说我要在运行时 * 让他起作用,这也不难理解,你想啊,咱们的javabean 要存到数据库肯定是动态执行时的,所以选择 RetentionPolicy.RUNTIME * 关于这个选项,可参见文档说明, 一看就明白,不多说了 * 不明白也不要紧,带着疑惑往下看 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Table { //关于这个value方法,如果你只有一个属性,当我们value()时,使用的时候就不需要指明是哪个属性了,直接填值就可以了 String value(); } /** * 这个是要用在字段上,所以我们选择 ElementType.FIELD */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String value(); }

一般的我们要往数据库里存东西,都会定义一个Java类来存储数据,里面的字段和数据库里的字段一一对应:

@Table("lijing") //上面我们提到了,@Table这个注解是给类用的(ElementType.TYPE),是不是解除了上面的疑惑 “lijing” 就是我们定义的表名 public class Person { @Column("name") // 这里的name要和我们数据库的字段保持一致(这样说不太严谨,只要能和数据库的字段保持一一对应就行,不明白也不要纠结,那我们就写一致),在下面我们会明白 private String name; @Column("address") private String address; @Column("email") private String email; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }

好了,我们现在测试一下

public class AnnotationTest { public static void main(String[] args) { Person person1 = new Person(); person1.setName("xiaoli"); Person person2 = new Person(); person2.setAddress("北京"); Person person3 = new Person(); person3.setEmail("5555@qq.com, 163333@163.com"); String query1 = query(person1); String query2 = query(person2); String query3 = query(person3); System.out.println(query1); System.out.println(query2); System.out.println(query3); } /** * 根据Person 这个对象里面的字段名和字段值来生成sql语句 * @param person * @return */ public static String query(Person person) { StringBuffer sql = new StringBuffer(); //这里用到了反射,不会反射的朋友也不要惊慌,在这我大致概括一下反射的使用过程 //1,先获取类对象 Class //2,根据Class对象来获取Class里面的字段和方法 //3,在通过某个方法获取Object对象的字段的值或者调用Object的方法 //第一步, Class clazz = person.getClass(); // 这里就是检测一下传进来的对象的类对象有没有用到我们定义的注解,没什么好说,记住这些方法 boolean exist = clazz.isAnnotationPresent(Table.class); if (!exist) return null; //获取注解的值,这里就是数据库表名 Table table = (Table) clazz.getAnnotation(Table.class); String tableName = table.value(); //这里的" where 1 = 1"就是防止没有判断语句而导致sql语句不完整 sql.append("select * from ").append(tableName).append(" where 1 = 1"); //第二步 获取所有的字段,不管是public还是private,统统的拿到 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { //还是判断一下这个字段有没有用到注解 boolean existColunm = field.isAnnotationPresent(Column.class); if (existColunm){ //数据库里面的字段 Column column = field.getAnnotation(Column.class); String columnalue = column.value(); //到底看看这是javabean哪个属性 String fieldName = field.getName(); //根据属性名来找到get方法,下面的写法不是固定的,随机应变 String methodName = "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1); try { //看到了没,这就是第三步 Object invoke = clazz.getMethod(methodName).invoke(person); if (invoke != null){ sql.append(" and ").append(columnalue).append("=").append(invoke); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } return sql.toString(); } } 运行结果 select * from lijing where 1 = 1 and name=xiaoli select * from lijing where 1 = 1 and address=北京 select * from lijing where 1 = 1 and email=5555@qq.com, 163333@163.com

其实呢些框架也是这么个用法,多用就熟练了

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 0:50:53

MVDR与常规波束形成对比:原理、Python实现与工程避坑指南

简介:这份资源面向信号处理、无线通信与声学阵列方向的学习者与工程人员,聚焦常规波束形成与MVDR(Capon)波束形成的原理实现与对比。常规波束形成通过加权求和形成指向性合成信号,计算简单但干扰抑制有限;M…

作者头像 李华
网站建设 2026/10/30 0:48:26

Xiuno Light轻鸿v3.3主题:安装避坑与CSS变量定制指南

简介:一份已实测的Xiuno Light(修罗轻鸿)v3.3论坛主题升级版,面向论坛站长、管理员及二次开发爱好者。该版本在功能定制、性能优化、安全加固与用户体验方面均有提升,可帮助社区快速获得更现代的界面和更稳定的运行环境…

作者头像 李华
网站建设 2026/10/30 0:47:51

用OpenShell拯救Win11开始菜单:高效自定义布局与避坑指南

前阵子我把主力机从 Windows 10 一路升到 Windows 11,新系统界面确实清爽了不少,可那个开始菜单是真把我劝退了:磁贴和推荐内容挤在一排,我想要的应用要么埋在一长串字母表里,要么被“推荐的项目”顶到好几屏之外。后来…

作者头像 李华
网站建设 2026/10/30 0:47:45

RAG 从原理到实践:混合检索、重排序与效果评估的工程全解析

RAG 从原理到实践:混合检索、重排序与效果评估的工程全解析 大模型一本正经地胡说八道,这个场景应该不陌生。问它一个具体业务问题,它逻辑顺滑地给你编了一个看似合理实则完全错误的答案。早期大家靠调整提示词,后来发现治标不治本…

作者头像 李华
网站建设 2026/10/30 0:45:26

Skills:AI Agent时代可验证、可沙盒化的能力封装范式

1. “Skills”不是功能模块,而是AI Agent时代的新型能力封装范式最近两周,我在三个不同技术团队的内部分享会上,都被问到同一个问题:“你们说的skills到底指什么?是插件?是函数?还是某种新API&a…

作者头像 李华
网站建设 2026/10/30 0:43:14

PQ分解法实战:电力系统潮流计算的高效降维求解器

简介:本资源是一份面向电力系统专业本科生、研究生及工程实践者的潮流计算MATLAB实现工具,聚焦PQ分解法这一经典数值算法,解决六节点规模电网的稳态电压与功率分布分析问题。压缩包为1KB的ZIP文件,内含1个核心MATLAB脚本&#xff…

作者头像 李华