这次给大家介绍一下在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语句的更多相关文章

  1. Java反射与自定义注解

    反射,在Java常用框架中屡见不鲜.它存在于java.lang.reflact包中,就我的认识,它可以拿到类的字段和方法,及构造方法,还可以生成对象实例等.对深入的机制我暂时还不了解,本篇文章着重在使 ...

  2. Java:深入自定义注解(Annotation)

    在网上找了很多资料也有写的比较好的,但是总有有一点半点的细节没有写出来,在这里自己总结下使用. 使用Java的自定义注解,首先个人需要了解下Java为我们提供的元注解和相关定义注解的语法.(这个我在网 ...

  3. C#反射生成简单sql语句

    static void Main(string[] args) { book book = new book();//实体类 booktest b1 = new booktest(); book.bo ...

  4. Java反射reflection与注解annotation的应用(自动测试机)

    一.关于自动测试机 1.什么是自动测试机? 对类中的指定方法进行批量测试的工具 2.自动测试机有什么用? a.避免了冗长的测试代码 当类中的成员方法很多时,对应的测试代码可能会很长,使用测试能够让测试 ...

  5. Android面试基础(一)IOC(DI)框架(ViewUtils)讲解_反射和自定义注解类

    1. Android中的IOC(DI)框架 1.1 ViewUtils简介(xUtils中的四大部分之一) IOC: Inverse of Controller 控制反转. DI: Dependenc ...

  6. springmvc之自定义注解(annotation)

    参考:日志处理 三:Filter+自定义注解实现 系统日志跟踪功能 1.项目结构 2.pom.xml,添加需要依赖 <project xmlns="http://maven.apach ...

  7. 【spring】自定义注解 custom annotation

    自定义注解 custom annotation 使用场景 类属性自动赋值. 验证对象属性完整性. 代替配置文件功能,像spring基于注解的配置. 可以生成文档,像java代码注释中的@see,@pa ...

  8. 利用反射跟自定义注解拼接实体对象的查询SQL

    前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...

  9. JUnit 4 使用 Java 5 中的注解(annotation)

    JUnit 4 使用 Java 5 中的注解(annotation),以下是JUnit 4 常用的几个 annotation 介绍@Before:初始化方法@After:释放资源@Test:测试方法, ...

随机推荐

  1. 如何在linux下解压缩rar和zip格式的文件压缩包

    转载:http://oldboy.blog.51cto.com/2561410/597515 使用apt-get安装:  sudo apt-get install  rar  zip rar使用: 将 ...

  2. 无法挂载 “7.9 GB Filesystem”.

    有个8G的U盘,格式化成exfat格式.插入电脑后点击盘符,弹出错误提示: 无法挂载 “7.9 GB Filesystem”. Error mounting: mount exited with ex ...

  3. mongoDB 插入数据 用java实现

    import java.net.UnknownHostException; import com.mongodb.BasicDBObject; import com.mongodb.DB; impor ...

  4. Node.js连接Mysql

    1.安装 npm install mysql 注意要复制node_modules到当前工程的文件夹中 2.基本连接 /** * Created by Administrator on 13-12-25 ...

  5. javaweb学习总结十五(web开发的相关概念以及常用服务器介绍)

    一:java web开发的相关概念 1:web分为静态web和动态web 2:模拟web服务器 web页面如果想让外部网络访问,必须通过网络程序读取资源,流程: a:用户通过浏览器访问网络程序 b:网 ...

  6. python django第二弹

    每天晚上应该就这样坐着,然后把每天的东西做个总结,或大或小,有的人可能愿意把自己的东西保留在草稿箱,想想我还是把他写出来吧,前几次我发现又遇到了之前遇到的简单的问题,翻看自己之前写的几篇小日记,可以很 ...

  7. CF A and B and Team Training (数学)

    A and B and Team Training time limit per test 1 second memory limit per test 256 megabytes input sta ...

  8. C# 学习笔记01

    想写一个app可以访问数据库,实现对数据库的查询,修改等,突然发现知识实在有限,故选择C#来实现此app. 使用简单的三层架构来作为此app的架构.表现层(UI).业务逻辑层(BLL).数据访问层(D ...

  9. MyBatis(3.2.3) - ResultMaps: Extending ResultMaps

    ResultMaps are used to map the SQL SELECT statement's results to JavaBeans properties. We can define ...

  10. Linux 命令 - passwd: 更改用户密码

    命令格式 passwd  [-k]  [-l]  [-u  [-f]] [-d] [-e] [-n mindays] [-x maxdays] [-w warndays] [-i inactiveda ...