使用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:测试方法, ...
随机推荐
- centos、linux改变ll命令显示颜色
服务器用的centOS,用putty管理时,在命令行下目录用蓝色显示,很难看清.可以用以下两种方法改变: 方法一: 1.直接修改个人帐户目录下的.color.rc文件. 找到 DIR 01;34,修改 ...
- c# 友元程序集
在团队开发中,如果一个程序集中要调用另外一个程序集,但是要被调用的那个程序集又不想用public来公开自己的类, 那么怎么办,就是用最后一种internal来用来做类的可见性了. 下面来看一个简单例子 ...
- LeetCode 213
House Robber II Note: This is an extension of House Robber. After robbing those houses on that stree ...
- 关于Hadoop之父Doug Cutting
生活中,可能所有人都间接用过他的作品,他是Lucene.Nutch .Hadoop等项目的发起人.是他,把高深莫测的搜索技术形成产品,贡献给普罗大众:还是他,打造了目前在云计算和大数据领域里如日中天的 ...
- Netty学习链接
Netty实战精髓请参见:https://waylau.gitbooks.io/essential-netty-in-action/content/GETTING%20STARTED/Introduc ...
- hdu1560 搜索
从原串的最大长度开始枚举,当某个长度的值能保存所有串时,即成功.对每个长度进行深搜,每次取某个串的第一个. #include<iostream> #include<cstdio> ...
- Sublime Text—安装
一.简介 市面上的编辑器纷繁复杂各有优点,好用的编辑器能让你工作事半功倍,先简单介绍下本文主角Sublime Text编辑器,下面简称Sublime. 1.可用于 Windows.Mac OS X 和 ...
- PL/SQL Developer连接远程Oracle数据库
转自:http://zhengdu.net/archives/152 一.首先看远程端oracle服务是否启动 如果没有启动,请启动oracle服务 ps:创建或者删除oracle监听 二.远程端or ...
- sql常识-FULL JOIN
SQL FULL JOIN 关键字 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行. FULL JOIN 关键字语法 SELECT column_name(s) FROM table_n ...
- Android虚拟机运行问题之小结
首先说一下关于虚拟机的技巧,以前我也总是感觉电脑运行虚拟机的时候老是卡,后来在看课堂直播时看到老师用的是Total Control,在网上搜“Total Control”就能能找到,比系统自带SDK运 ...