说明:本文将采用倒叙方式陈述注解处理器
1.先看结果,抛砖引玉
为annotations.javabean.Member创建的SQL:
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30) NOT NULL);
为annotations.javabean.Member创建的SQL:
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30) NOT NULL,
LASTNAME VARCHAR(50) NOT NULL);
为annotations.javabean.Member创建的SQL:
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30) NOT NULL,
LASTNAME VARCHAR(50) NOT NULL,
AGE INT NOT NULL);
为annotations.javabean.Member创建的SQL:
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30) NOT NULL,
LASTNAME VARCHAR(50) NOT NULL,
AGE INT NOT NULL,
HANDLE VARCHAR(30) NOT NULL PRIMARY KEY);
2.注解处理器代码(运行时在IDE中进行参数配置对应javabean的全限定名)
package annotations.ImplAnnotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import annotations.database.Constraints;
import annotations.database.DBTable;
import annotations.database.SQLInteger;
import annotations.database.SQLString;
public class TableCreater {
public static void main(String[] args) throws ClassNotFoundException {
if(args.length<1){
System.out.println("参数是注解类型");
System.exit(0);
}
for(String className:args){
//通过反射机制获取“全类名”对应的Class对象
Class<?> cl = Class.forName(className);
//获取DBTable注解
DBTable dbTable = cl.getAnnotation(DBTable.class);
//判断是类中是否有DBTable注解
if(dbTable == null){
System.out.println("类中没有DBTable注解:"+className);
continue;
}
String tableName = dbTable.name();
/*
* 如果DBTable注解存在,但长度小于1
* ("".length()=0),则取对应
* 类名作为表名
* */
if(tableName.length() < 1){
tableName = cl.getName().toUpperCase();
}
List<String> columnDefs = new ArrayList<String>();
/*
*1.通过反射机制依次获取类中属性对应的注解
*
*3.
* */
for (Field field:cl.getDeclaredFields()) {
String columnName = null;
Annotation[] anns = field.getDeclaredAnnotations();
if(anns.length < 1) continue; //not a db table column
//2.对获取到的注解进行instanceof判断
if(anns[0] instanceof SQLInteger){
SQLInteger sInt = (SQLInteger) anns[0];
//如果没有指定SQLInteger注解的name,则将类中属性名称作为数据库列名
if(sInt.name().length() < 1)
columnName = field.getName().toUpperCase();
else
columnName = sInt.name();
columnDefs.add(columnName+" INT"+getConstraints(sInt.constraints()));
}
//2.对获取到的注解进行instanceof判断
if(anns[0] instanceof SQLString){
SQLString sString = (SQLString) anns[0];
//空字符串 判断
if(sString.name().length() < 1)
columnName = field.getName().toUpperCase();
else
columnName = sString.name();
columnDefs.add(columnName+" VARCHAR("+
sString.value()+")"+getConstraints(sString.constraints()));
}
StringBuilder createCommand = new StringBuilder(
"CREATE TABLE "+tableName+"(");
String tableCreate = "";
for (String columnDef : columnDefs) {
createCommand.append("\n " + columnDef + ",");
tableCreate = createCommand.substring(
0,createCommand.length()-1)+");";
}
//循环输出每次SQL拼接结果
System.out.println("为"+className+"创建的SQL: "+
"\n "+ tableCreate+"\n ");
}
}
}
/*
* 获取约束的方法
* */
private static String getConstraints(Constraints con){
String constraints = "";
if(!con.allowNull())
constraints += " NOT NULL";
if(con.primaryKey())
constraints += " PRIMARY KEY";
if(con.unique())
constraints += " UNIQUE";
return constraints;
}
}
3.背注解的javabean
package annotations.javabean;
import annotations.database.Constraints;
import annotations.database.DBTable;
import annotations.database.SQLInteger;
import annotations.database.SQLString;
@DBTable(name="MEMBER")//表名
public class Member {
//长度30
@SQLString(30)
String firstName;
//长度50
@SQLString(50) String lastName;
@SQLInteger Integer age;
@SQLString(value=30,constraints=
@Constraints(primaryKey=true))
String handle;
static int memberCount;
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Integer getAge() {
return age;
}
public String getHandle() {
return handle;
}
@Override
public String toString(){
return handle;
}
}
4.注解类
4.1注解类DBTable
package annotations.database;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)//应用目标:接口、类、枚举、注解
@Retention(RetentionPolicy.RUNTIME)//保留策略:运行时
public @interface DBTable {//数据库注解
public String name() default "";
}
4.2注解类Constraints
package annotations.database;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)//应用目标:字段、枚举的常量
@Retention(RetentionPolicy.RUNTIME)//保留策略:运行时
public @interface Constraints {//约束注解
boolean primaryKey() default false;
boolean allowNull() default false;
boolean unique() default false;
}
4.3注解类Uniqueness
package annotations.database;
public @interface Uniqueness {
Constraints constraints()
default @Constraints(unique=true);
}
4.4注解类SQLString
package annotations.database;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)//应用目标:字段、枚举的常量
@Retention(RetentionPolicy.RUNTIME)//保留策略:运行时
public @interface SQLString {
int value() default 0;
String name() default "";
/*
* 注解类型的...
* */
Constraints constraints() default @Constraints;
}
4.5注解类SQLInteger
package annotations.database;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)//应用目标:字段、枚举的常量
@Retention(RetentionPolicy.RUNTIME)//保留策略:运行时
public @interface SQLInteger {
String name() default "";
//注解类型的...
Constraints constraints() default @Constraints;
}