您的位置:首页 > 编程语言 > Java开发

JAVA注解 实现一个简单的sql语句生成器

2015-07-29 17:22 806 查看
注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁。

注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致。Java SE5内置了三种标准注解:

@Override,表示当前的方法定义将覆盖超类中的方法。

@Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。

@SuppressWarnings,关闭不当编译器警告信息。


上面这三个注解多少我们都会在写代码的时候遇到。Java还提供了4中注解,专门负责新注解的创建。

1.@Target(ElementType)  用于制定限定注解的使用范围
ElementType属性详解(jdk java.lang.annotation):


public enum ElementType{
TYPE,
//用于类,接口,枚举但不能是注解
FIELD,
//字段上,包括枚举值
METHOD,
//方法,不包括构造方法
PARAMETER,
//方法的参数
CONSTRUCTOR,
//构造方法
LOCAL_VARIABLE,
//本地变量或catch语句
ANNOTATION_TYPE,
//注解类型(无数据)PACKAGE//Java包
}


2.@Retention(RetentionPolicy) 用于制定编译器处理策略

RetentionPolicy属性详解(jdk java.lang.annotation):

publicenumRetentionPolicy{
SOURCE,
//此类型会被编译器丢弃
CLASS,
//此类型注解会保留在class文件中,但JVM会忽略它
RUNTIME
//此类型注解会保留在class文件中,JVM会读取它
}


3.@Documented 用于制定文档化功能

注意使用此注解时必须设置RetentionPolicy为RUNTIME

4.@Inherited 用于指定允许继承

下面介绍一个注解具体使用实例:动态生成sql语句。

首先定义注解,表名注解@Table和列注解@Column

@Target({ElementType.TYPE}) //类或接口可用
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {

String value(); //可以有多个值,一个值就必须写value,否则会报错
}

@Target({ElementType.FIELD}) //类或接口可用
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {

String value(); //一个值就必须写value
}


然后创建与数据库信息对应的Model类,在其中加入注解。

@Table("User")
public class User {

@Column("id")
private int id1;

@Column("userName")
private String userName1;

@Column("nickname")
private String nickname1;

@Column("age")
private int age1;

@Column("city")
private String city1;

public int getId1() {
return id1;
}

public void setId1(int id1) {
this.id1 = id1;
}

public String getUserName1() {
return userName1;
}

public void setUserName1(String userName1) {
this.userName1 = userName1;
}

public String getNickname1() {
return nickname1;
}

public void setNickname1(String nickname1) {
this.nickname1 = nickname1;
}

public int getAge1() {
return age1;
}

public void setAge1(int age1) {
this.age1 = age1;
}

public String getCity1() {
return city1;
}

public void setCity1(String city1) {
this.city1 = city1;
}
}

@Table("department")
public class Department {

@Column("id")
private int id1;

@Column("name")
private String name1;

@Column("leader")
private String leader1;

public int getId1() {
return id1;
}

public void setId1(int id1) {
this.id1 = id1;
}

public String getName1() {
return name1;
}

public void setName1(String name1) {
this.name1 = name1;
}

public String getLeader1() {
return leader1;
}

public void setLeader1(String leader1) {
this.leader1 = leader1;
}
}


下面是用于动态生成Sql语句的方法,传入一个加入@Table和@Column注解的Model类对象。功能还不完善,读者有具体需求可自己增加更复杂的sql动态生成功能。

public static String query(Object f){

StringBuilder sb = new StringBuilder();

//1.获取到class
Class c  = f.getClass();
//2获取到table的名字
boolean exists = c.isAnnotationPresent(Table.class);
if(!exists) return null;
Table t = (Table)c.getAnnotation(Table.class);
String tableName = t.value();
sb.append("select * from ").append(tableName).append(" where 1=1");

//3.遍历所有的字段
Field[] fArray = c.getDeclaredFields();
for(Field field:fArray){

//4.处理每个字段对应的sql
//4.1 拿到字段名
boolean fexists = field.isAnnotationPresent(Column.class);
if(!fexists) continue;

Column column = field.getAnnotation(Column.class);
String columnName = column.value();

//4.2 拿到字段的值  通过反射
String fieldName = field.getName();
String getMethidName = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
Object fieldValue = null;
try {
Method getMethod = c.getMethod(getMethidName);
fieldValue = getMethod.invoke(f);
} catch (Exception e) {
e.printStackTrace();
}
if(fieldValue == null || (fieldValue instanceof Integer && (Integer)fieldValue == 0)) continue;
//4.3 拼装sql
//          System.out.println(fieldValue.toString());
if(fieldValue instanceof String) {

if(((String) fieldValue).contains(",")){

sb.append(" and ").append(columnName).append(" in (");
String[] args =fieldValue.toString().split(",");
for(String str:args){
sb.append("\'").append(str).append("\',");
}
sb.deleteCharAt(sb.length()-1); //删除最后一个逗号
sb.append(")");
}
else{

sb.append(" and ").append(columnName).append("=").append("\'").append(fieldValue.toString()).append("\'");
}
}
else if(fieldValue instanceof Integer){
sb.append(" and ").append(columnName).append("=").append(fieldValue.toString());
}
}

return sb.toString();
}


接着进行测试:

public static void main(String[] args) {

User f1 = new User();
f1.setId1(10);

User f2 = new User();
f2.setUserName1("lucy");

User f3 = new User();
f3.setCity1("shenzhen,guangzhou,zhuhai");
f3.setNickname1("wahaha");
f3.setUserName1("username");

System.out.println(query(f1));
System.out.println(query(f2));
System.out.println(query(f3));

Department d1 = new Department();
d1.setLeader1("大领导");
d1.setId1(0);

Department d2 = new Department();
d2.setId1(2);

System.out.println(query(d1));
System.out.println(query(d2));
}


打印结果:

select * from User where 1=1 and id=10
select * from User where 1=1 and userName='lucy'
select * from User where 1=1 and userName='username' and nickname='wahaha' and city in ('shenzhen','guangzhou','zhuhai')
select * from department where 1=1 and leader='大领导'
select * from department where 1=1 and id=2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: