注解
Annotation是java5引入的特征。
元注解:注解的注解
@Target | 描述注解的使用范围(类、方法、属性、参数、包等等) |
---|---|
@Retention | 描述注解的有效的时间(运行时、编译时、源代码) |
@Document | 注解是否包含在文档里 |
@Inherited | 是否可被继承 |
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
注解中定义的看起来像方法,其实是注解中的属性
例子
摘抄自《java编程思想》
一个使用注解生成建表语句的,注解和对应处理器
自定义注解
/**
* 加在要生成数据库表的类上的注解,可定义表名称
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
public String name() default "";
}
约数
//定义键的 非空、唯一键、主键属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints{
boolean primaryKey() default false;//主键
boolean allowNull() default true;//非空
boolean unique()default false;//唯一键
}
/**唯一键注解
*/
public @interface Uniqueness {
Constraints constraintsv() default @Constraints(unique = true);
}
字段属性
// int类型键的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
String name() default "";
Constraints constraints() default @Constraints;
}
// String类型键的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
int value() default 0;
String name() default "";
Constraints constraints() default @Constraints;
}
使用注解的类
/**
* 简单的bean,由这个类生成对应的表
*/
@DBTable(name = "MEMBER")
public class Member {
@SQLString(30)
String firstName;
@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 String getHandle() {
return handle;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return handle;
}
}
注解的处理器
/**
* 生成建表语句
*
* 注解处理器,很有意思,通过反射获取方法,域,注解等属性,然后按照自己的想法处理。
* 注解的name(),一些方法都很有用。
* 可以多看看其他源码,更加了解注解
*/
public class TableCreator {
public static void main(String[] args) throws Exception {
String[] classes = {"main.java.y19m12.annotation.database.Member"};
// 遍历所有的符号条件的类
for (String className:classes){
Class<?> clazz = Class.forName(className);
DBTable dbTable = clazz.getAnnotation(DBTable.class);
// 找到带有@DBTable注解的类
if (dbTable==null){
System.out.println("No DBTable annotations in class"+className);
continue;
}
// 表名
String tableName = dbTable.name();
if (tableName.length()<1){//当没有给定表名时
tableName=clazz.getName().toUpperCase();
}
List<String> columnDefs = new ArrayList<String>();//列属性
for (Field field:clazz.getDeclaredFields()){
String columnName = null;//列名
Annotation[] anns =field.getDeclaredAnnotations();//获取属性的注解
if (anns.length<1){
continue;
}
if (anns[0] instanceof SQLInteger){// 是int类型的键
SQLInteger sInt = (SQLInteger) anns[0];
if (sInt.name().length()<1){
columnName = field.getName().toUpperCase();
}else {
columnName = sInt.name();
}
columnDefs.add(columnName+" INT"+getConstraints(sInt.constraints()));
}
if (anns[0] instanceof SQLString){// 是string类型的键
SQLString sInt = (SQLString) anns[0];
if (sInt.name().length()<1){
columnName = field.getName().toUpperCase();
}else {
columnName = sInt.name();
}
columnDefs.add(columnName+" VARCHAR"+getConstraints(sInt.constraints()));
}
}
// 拼接字符串
StringBuilder createCommand = new StringBuilder(
"CREATE TABLE " + tableName +" (");
for (String columnDef:columnDefs){
createCommand.append("\n "+columnDef+",");
}
String tableCreate = createCommand.substring(0,createCommand.length()-1)+");";
System.out.println("Table Creation SQL for "+className+" is:\n"+tableCreate);
}
}
/**
* 获取键的属性,返回字符串
* @param con
* @return
*/
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;
}
}