JAVA中的注解技术(二)
在关系数据库中,每个表中的各个字段都有特定的含义,并且字段与字段之间存在某种联系。所以我们可以通过对象/关系映射的方式,将JavaBean对象存储在数据库中。下面我们就实现这一功能。
一、首先定义一个注解来标注表名
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 ""; //用来指定表名 }
二、对表中的每个字段定义注解
1.首先定义约束注解(用来标注该字段是否为主键、是否为空)
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 Contraints { boolean primaryKey() default false; //确定该字段是否为主键 boolean unique() default false; //确定该字段是否唯一 boolean allowNull() default false; //确定该字段是否为空 }
2.定义字符串类型的注解
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 ""; //定义字段名 Contraints constraints() default @Contraints; //注解嵌套 }
3.定义整型的注解
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 ""; //字段名 Contraints contraints() default @Contraints; //注解嵌套 }
三、对Bean进行注解
package annotations.database; @DBTable(name = "MEMBER") //定义表名为MEMBER public class Member { @SQLString(30) //该字段的长度为30个字符 String firstName; @SQLString(30) String lastName; @SQLInteger Integer age; @SQLString(value = 30, constraints = @Contraints(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; } public String toString() { return handle; } }
四、注解处理器的实现
package annotations.database; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; public class TableCreator { public static void main(String[] args) throws ClassNotFoundException { if (args.length < 1) { System.out.println("参数:使用注解的class文件"); System.exit(0); } for (String className : args) { Class<?> c1 = Class.forName(className); //将传入的class文件转变为CLASS对象 DBTable dbTable = c1.getAnnotation(DBTable.class); //获取Member中使用到的DBTable注解 if (dbTable == null) { System.out.println(className + "中没有使用DBTable注解"); continue; } String tableName = dbTable.name(); //获取表名 if (tableName.length() < 1) tableName = c1.getName().toUpperCase(); //获取类名,并将其作为表名 List<String> columnDefs = new ArrayList<String>(); for (Field field : c1.getDeclaredFields()) { //遍历Member中所有的属性 String columnName = null; Annotation[] anns = field.getDeclaredAnnotations(); //获取该属性上的所有注解 if (anns.length < 1) continue; if (anns[0] instanceof SQLInteger) { SQLInteger sInt = (SQLInteger) anns[0]; if (sInt.name().length() < 1) columnName = field.getName().toUpperCase(); //将属性名作为字段名 else { columnName = sInt.name(); //使用注解中指定的字段名 } columnDefs.add(columnName + "INT" + getConstraints(sInt.contraints())); //获取字段的约束条件 } 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 " //使用StringBuilder来构造SQL语句 + tableName + "("); for (String columnDef : columnDefs) createCommand.append("\n " + columnDef + "."); String tableCreate = createCommand.substring(0, createCommand.length() - 1) + "\n);\n"; System.out.println("Table CREATE SQL for " + className + " is : \n" + tableCreate); } } } private static String getConstraints(Contraints con) { //对约束注解中的每个字段进行访问 String constraints = ""; if (!con.allowNull()) constraints += "NOT NULL "; if (!con.primaryKey()) constraints += "PRIMARY KEY"; if (con.unique()) constraints += "UNIQUE"; return constraints; } }
以上的代码来自《JAVA编程思想》一书,在此仅仅用于学习交流。
从以上的代码可以看出注解就是一个特殊Bean类,里面可以存储一些元数据。通过处理器来获取这些元数据,实现相应的功能。其主要作用还是为了减少程序员的工作量,提高代码的可用性、可扩张性。

浙公网安备 33010602011771号