注解的定义
注解(也被称为元数据
)为我们在代码中添加信息提供了一种形式化的方式,使我们可以在稍后某个时刻非常方便地使用这些数据.
注解基本概念
基本注解
java SE5内置了三种,定义在java.lang中的注解提供使用
@Override 表示当前的方法定义将覆盖超类中的方法. @Deprecated 标识为启用,在使用这个元素时会有警告提示 @SuppressWarnings 关闭不当的编译器警告信息
另外提供了四种注解(元注解),用于创建注解.
@Target 用来定义你的注解将应用在什么地方 可选的ElementType类型
CONSTRUCTOR:构造器的声明
FIELD:域账号(包括enum实例)
LOCAL_VARLABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明@Retention 表示需要在什么级别保存该注解信息 可选的RetentionPolicy类型
SOURCE:源代码
CLASS:类文件
RUNTIME:运行时@Documented 将此注解包含在javadoc中 @Inherited 运行子类继承父类中的注解
注解元素
注解可以添加的元素:
所有基本类型(int float double boolean等) String Class enum Annotation 以上的数组类型
没有元素的注解称为标记注解(marker annotation)
例如@Override
使用注意事项
默认值限制 编译器对元素的默认值很挑剔,元素不能有不确定的值(元素必须有默认值,或者使用时设置).默认值不能为null,可以使用""或者负数来自己标识某个元素不存在. 注解不可继承.可以使用注解上加注解,或者元素上使用注解来实现这个功能
注解的使用案例 -- 使用注解实现自动生成创建表sql功能
自定义注解
使用元注解来创建自定义注解使用,是最基础的功能,按照上文的定义创建注解.
创建一个对应数据库DB的注解 @DBTable
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
public String name() default ""; //表名
}
创建一个带注解元素的注解 @SQLInteger
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
String name() default "";
Constraints constraints() default @Constraints;
}
创建约束条件注解 @Constraints
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
/**
* 主键
*/
public boolean primaryKey() default false;
/**
* 是否可以为空
* @return
*/
public boolean allowNull() default true;
/**
* 是否唯一
* @return
*/
public boolean unique() default false;
}
使用注解
前面我们已经创建了注解,那么就需要使用起来.
创建一个和数据库对应用的entity类 Member
@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 handel;
static int memberCount;
public String getHandel(){
return handel;
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public String toString(){
return handel;
}
public Integer getAge(){
return age;
}
}
注解处理器
在注解创建好以后,需要自己实现自己的注解处理器
,来对注解进行处理.如果没有注解处理器的话,注解的功能就等同于注释了.
现在写一个实现读取注解生成sql的注解处理器TableCreator
public class TableCreator {
public static void main(String[] args) throws ClassNotFoundException {
String[] args2 = {"db.Member"};
if (args2.length<1){
System.out.println("arguments: annotated classes");
System.exit(0);
}
for (String className : args2) {
Class<?> cl = Class.forName(className);
//获取 dbTable注解类
DBTable dbTable = cl.getAnnotation(DBTable.class);
if (dbTable==null){
System.out.println("No DB table in class"+className);
continue;
}
String tableName = dbTable.name();
//如果db.Member无表名 用类名
if (tableName.length()<1){
tableName = cl.getName().toUpperCase();
System.out.println("cl.name:"+cl.getName());
System.out.println("tableName:"+tableName);
}
List<String> columnDefs = new ArrayList<String>();
//获取类的所有元素
for (Field field : cl.getDeclaredFields()) {
String columnName = null;
//从元素中获取注解类型
Annotation[] anns = field.getDeclaredAnnotations();
if (anns.length<1){
continue;
}
//如果是SQLInteger类型 获取
if (anns[0] instanceof SQLInteger){
SQLInteger sqlInteger = (SQLInteger) anns[0];
//如果无元素名称 使用类名
columnName = sqlInteger.name().length()<1?field.getName().toUpperCase():sqlInteger.name();
columnDefs.add(columnName+" INT"+getConstraints(sqlInteger.constraints()));
}
//其他类型 依次填写
if (anns[0] instanceof SQLString){
SQLString sqlString = (SQLString) anns[0];
//如果无元素名称 使用类名
columnName = sqlString.name().length()<1?field.getName().toUpperCase():sqlString.name();
columnDefs.add(columnName+" VARCHAR("+sqlString.value()+")"+getConstraints(sqlString.constraints()));
}
//拼接创建sql
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("创建表的sql为: \n"+tableCreate);
}
}
}
public static String getConstraints(Constraints constraints){
String constraintsStr = "";
if (!constraints.allowNull()){
constraintsStr+=" NOT NULL";
}
if (constraints.primaryKey()){
constraintsStr+=" PRIMARY KEY";
}
if (constraints.unique()){
constraintsStr+=" UNIQUE";
}
return constraintsStr;
}
}
运行结果
创建表的sql为:
CREATE TABLE Member(
FIRSTNAME VARCHAR(30)
创建表的sql为:
CREATE TABLE Member(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50)
创建表的sql为:
CREATE TABLE Member(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50),
AGE INT
创建表的sql为:
CREATE TABLE Member(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50),
AGE INT,
HANDEL VARCHAR(30) PRIMARY KEY
这样我们就实现了一个使用注解来自动生成数据库表创建sql的小功能.那么你学会注解的使用了吗?
java培训班:http://www.baizhiedu.com/java2019