使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句
这次给大家介绍一下在Java开发过程中 使用自定义注解开发:
主要知识点:
1.反射 主要用于提取注解信息
2.自定义异常 主要是为了自己自定义一个异常信息
3.自定义注解 本次重点 学会如何自定义注解以及如何使用反射提取注解信息运用到实际开发
下图表示在Java中注解的含义以及注解的分类和如何解析注解
**
*
*/
/**
* ClassName:package-info.java
* @author xg.qiu
* @since JDK1.7
* Aug 3, 2015
* 使用自定义注解:
* @Target :用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
* 取值(ElementType)有:
1.ElementType.CONSTRUCTOR:用于描述构造器
2.ElementType.FIELD:用于描述域
3.ElementType.LOCAL_VARIABLE:用于描述局部变量
4.ElementType.METHOD:用于描述方法
5.ElementType.PACKAGE:用于描述包
6.ElementType.PARAMETER:用于描述参数
7.ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention :@Retention定义了该Annotation被保留的时间长短
取值(RetentionPoicy)有:
1.RetentionPolicy.SOURCE:在源文件中有效(即源文件保留)
2.RetentionPolicy.CLASS:在class文件中有效(即class保留)
3.RetentionPolicy.RUNTIME:在运行时有效(即运行时保留)
@Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,
因此可以被例如javadoc此类的工具文档化。
Documented是一个标识注解,没有成员。
@Inherited :元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的
[必须是extend class 而不是implements interface]
*/
package com.demo.ann;
注解语法:
public @interface 注解名{
// 注解变量
// 元数据类型:基本数据类型 String class enum Annotation 以及上述类型数组
// 如果元数据只有一个时 必须声明为value();
}
/**
*
*/
package com.demo.ann.anns;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* ClassName:Table.java
* @author xg.qiu
* @since JDK1.7
* Aug 3, 2015
* 自定义注解:表
* 用法:
* @Table("user")
* public class User
*/
@Target( ElementType.TYPE)// 作用域 类或接口
@Retention( RetentionPolicy.RUNTIME)// 有效期为运行时
public @interface Table {
String value();
}
/**
*
*/
package com.demo.ann;
import com.demo.ann.anns.Column;
import com.demo.ann.anns.Table;
/**
* ClassName:User.java
* JAVABean 用户实体类
* @author xg.qiu
* @since JDK1.7 Aug 3, 2015
*/
@Table("TABLE_USER")
public class User {
@Column("USER_ID")
private int userId;
@Column("USER_NAME")
private String userName;
@Column("PASS_WORD")
private String passWord;
@Column("AGE")
private int age;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/**
*
*/
package com.demo.ann.anns;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* ClassName:Column.java
* @author xg.qiu
* @since JDK1.7
* Aug 3, 2015
* 自定义注解:列
* 用法:
* @Column("userId")
* private int userId;
*/
@Target( ElementType.FIELD)//作用于属性
@Retention( RetentionPolicy.RUNTIME)//有效期为运行时
public @interface Column {
String value();
}
/**
*
*/
package com.demo.ann;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.demo.ann.anns.Column;
import com.demo.ann.anns.Table;
import com.demo.ann.exception.AnnException;
/**
解析注解并返回执行的sql语句
* ClassName:Test.java
* @author xg.qiu
* @since JDK1.7
* Aug 3, 2015
* 测试:使用自定义注解完成数据库的查询返回sql语句
* 1.根据id查询
* 2.根据用户名查询
* 3.根据用户名、密码组合查询
*/
public class Test {
public static void main(String[] args) {
User user1 = new User();
user1.setUserId(1);//根据Id查询
User user2 = new User();
user2.setUserName("xiaoqiu");// 根据用户名查询
User user3 = new User();
user3.setUserName("xiaoqiu");
user3.setPassWord("123456");// 根据用户名、密码组合查询
User user4 = new User();
user4.setUserName("xiaoqiu,zasang,lisi");
String sql1 = executeQuery(user1);
String sql2 = executeQuery(user2);
String sql3 = executeQuery(user3);
String sql4 = executeQuery(user4);
System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);
System.out.println(sql4);
}
/**
* @param user 用户对象
*@return String 返回的是拼装好的sql语句
*/
private static String executeQuery(User user) {
StringBuffer sb = new StringBuffer("select * from ");
//1、获取类
Class<? extends User> c = user.getClass();
//2、查找类是否被注解
boolean isExist = c.isAnnotationPresent(Table.class);
if(!isExist){
try {
// 自定义异常
throw new AnnException("the "+ c.getClass().getName() +" class is not used annotation");
} catch (AnnException e) {
e.printStackTrace();
}
}
// 获取Table注解
Table table = (Table) c.getAnnotation(Table.class);
sb.append( table.value() +" where 1= 1");
//3、查找属性是否被注解
Field[] fields = c.getDeclaredFields();
for(Field f : fields){
//3.1、处理每个字段对应的sql
//3.2、拿到字段值
boolean isFExist = f.isAnnotationPresent(Column.class);
if(!isFExist){
try {
throw new AnnException("the " + f.getName() +" field is not used annotation");
} catch (AnnException e) {
e.printStackTrace();
}
}
// 获取列注解
Column column = f.getAnnotation(Column.class);
String columnName = column.value();
//3.2、获取字段
String fieldName = f.getName();
//3.4、.拿到字段值
Object values = null;
String getFieldMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
try {
Method getMethod = c.getDeclaredMethod(getFieldMethodName);
values = getMethod.invoke(user);
//3.5.拼装sql
if( values == null || ( values instanceof Integer && (Integer) values == 0) ){
continue;
}
sb.append(" and ").append(columnName);
if(values instanceof Integer){
sb.append("=").append(values);
}else if(values instanceof String){
if( ((String) values).contains(",")){
String [] valuesIn = ((String) values).split(",");
sb.append(" in('");
for(String s : valuesIn){
sb.append(s).append("'").append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
}else{
sb.append("='").append(values).append("'");
}
}
} catch (Exception e) {
// 打印堆栈信息
e.printStackTrace();
}
}
// 返回拼装好的sql语句
return sb.toString();
}
}
运行效果:
select * from TABLE_USER where 1= 1 and USER_ID=1
select * from TABLE_USER where 1= 1 and USER_NAME='xiaoqiu'
select * from TABLE_USER where 1= 1 and USER_NAME='xiaoqiu' and PASS_WORD='123456'
select * from TABLE_USER where 1= 1 and USER_NAME in('xiaoqiu',zasang',lisi')
使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句的更多相关文章
- Java反射与自定义注解
反射,在Java常用框架中屡见不鲜.它存在于java.lang.reflact包中,就我的认识,它可以拿到类的字段和方法,及构造方法,还可以生成对象实例等.对深入的机制我暂时还不了解,本篇文章着重在使 ...
- Java:深入自定义注解(Annotation)
在网上找了很多资料也有写的比较好的,但是总有有一点半点的细节没有写出来,在这里自己总结下使用. 使用Java的自定义注解,首先个人需要了解下Java为我们提供的元注解和相关定义注解的语法.(这个我在网 ...
- C#反射生成简单sql语句
static void Main(string[] args) { book book = new book();//实体类 booktest b1 = new booktest(); book.bo ...
- Java反射reflection与注解annotation的应用(自动测试机)
一.关于自动测试机 1.什么是自动测试机? 对类中的指定方法进行批量测试的工具 2.自动测试机有什么用? a.避免了冗长的测试代码 当类中的成员方法很多时,对应的测试代码可能会很长,使用测试能够让测试 ...
- Android面试基础(一)IOC(DI)框架(ViewUtils)讲解_反射和自定义注解类
1. Android中的IOC(DI)框架 1.1 ViewUtils简介(xUtils中的四大部分之一) IOC: Inverse of Controller 控制反转. DI: Dependenc ...
- springmvc之自定义注解(annotation)
参考:日志处理 三:Filter+自定义注解实现 系统日志跟踪功能 1.项目结构 2.pom.xml,添加需要依赖 <project xmlns="http://maven.apach ...
- 【spring】自定义注解 custom annotation
自定义注解 custom annotation 使用场景 类属性自动赋值. 验证对象属性完整性. 代替配置文件功能,像spring基于注解的配置. 可以生成文档,像java代码注释中的@see,@pa ...
- 利用反射跟自定义注解拼接实体对象的查询SQL
前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...
- JUnit 4 使用 Java 5 中的注解(annotation)
JUnit 4 使用 Java 5 中的注解(annotation),以下是JUnit 4 常用的几个 annotation 介绍@Before:初始化方法@After:释放资源@Test:测试方法, ...
随机推荐
- MYSQL基础笔记(一)
关系型数据库概念: 1.什么是关系型数据库? 关系型数据库:是一种建立在关系模型(数学模型)上的数据库 关系模型:一种所谓建立在关系上的模型. 关系模型包含三个方面: 1.数据结构:数据存储的问题,二 ...
- css实现居中
--在html常常用到居中 --1.可以用<center></center> --2.可以用css 演示代码: <!DOCTYPE html PUBLIC "- ...
- LeetCode 338
Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the ...
- MSP430常见问题之通信类
Q1: 430 串口中,有个R/D 控制线,在接收上位机的数据,但本身的数据有无发送完毕不知道啊,什么时候才可置低R/d 位来接收数据啊?好像430 没有发送完中断标志A1:字节主动发送,一般都能发出 ...
- 【转】十二个移动App云测试服务盘点
随着移动设备.操作系统版本的碎片化,测试工作对于移动开发团队而言越来越成为一个沉重的包袱,不过这也带来了商机,现在市场上有不少服务和平台提供云测试工具,可以对移动App进行自动化测试,提供测试报告和优 ...
- css3 web字体记
css3 web字体 @font-face语法 @font-face能够加载服务器端的字体,让客户端浏览器显示客户端没有安装的字体. @font-face{ font-family:<YourW ...
- Bootstrap之导航栏(2015年-05年-20日)
<nav class="navbar navbar-default" style="border-color: transparent;">< ...
- fadein()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Jersey(1.19.1) - Client API, Testing services
The Jersey client API was originally developed to aid the testing of the Jersey server-side, primari ...
- ZooKeeper(3.4.5) - 配置伪集群模式
1. 准备 Java 运行环境,需要安装 Java1.6 或更高版本的 JDK. 2. 下载 ZooKeeper 的稳定版本 zookeeper-x.x.x.tar.gz,将其解压,约定目录名称为 % ...