注解的使用

在使用各种框架的时候,我经常会看到各种@,加了这个神奇的符号,我们就可以实现许多神奇的功能,这两天,我按照Thinking in java 的思路实现了一个简易的生成sql数据表的程序

DataTable 注解

package annotation.database;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author: miaoxu
 * @Description:
 * @Date: Created in 2017/11/14 0014
 * @Modified By :
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
    public String name() default "";
}

@Target注解用来说明这个注解应用的级别Type代表应用的是class,接口等,后面出现的Field代表应用的是变量@Retention表示需要在什么级别保存该注解信息,Running代表在运行期间也要保留注解,因此可以通过反射机制读取注解的信息这个注解的成员只有一个name方法,我们可以在使用注解的时候,给name赋值,如果没有指定值,默认值是空字符串,每个注解前面都会有@符号,代表这是一个注解,实际上,在idea中,直接创建class的时候,就可以选择创建注解。非常方便

constraints 注解

package annotation.database;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author: miaoxu
 * @Description:
 * @Date: Created in 2017/11/14 0014
 * @Modified By :
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
    boolean primaryKey() default false;
    boolean allowNull() default true;
    boolean unique() default false;
}

constrains实现的是数据库中对字段的约束,正如上面所定义的那样,常见的约束有是否是主键,是否允许为空等等,这个注解极大地方便了后面字段注解的实现

SQLString 注解

package annotation.database;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author: miaoxu
 * @Description:
 * @Date: Created in 2017/11/14 0014
 * @Modified By :
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
    int value() default 0;
    String name() default "";
    Constraints constrants() default @Constraints;
}

SQlString的value实际上是为了代表数据库中的varchar长度,name是字段名

package annotation.database;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author: miaoxu
 * @Description:
 * @Date: Created in 2017/11/14 0014
 * @Modified By :
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
    String name() default "";
    Constraints constraints() default @Constraints;
}

Member要生成的表

package annotation.database;

/**
 * @Author: miaoxu
 * @Description:
 * @Date: Created in 2017/11/14 0014
 * @Modified By :
 */
@DBTable(name = "member")
public class Member {
    @SQLString(30)
    String firstname;
    @SQLString(50)
    String lastname;
    @SQLInteger
    Integer age;
    @SQLString(value = 30, constrants = @Constraints(primaryKey = true))
    String handle;
    public String getHandle()
    {
        return handle;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return handle;
    }
}

Member类就是我们要生成的表

TableCreator类

package annotation.database;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: miaoxu
 * @Description:
 * @Date: Created in 2017/11/14 0014
 * @Modified By :
 */
public class TableCreator {
    public static void main(String[] args) throws Exception{
        if (args.length < 1)
        {
            System.out.println("arguments: annotated classes");;
        }

        for (String className: args)
        {
            Class<?> cl = Class.forName(className);
            DBTable dbTable= cl.getAnnotation(DBTable.class);
            if (dbTable == null)
            {
                System.out.println("No DBTable Annoation in class " + className);
                continue;
            }
            String tablename = dbTable.name();
            if (tablename.length() < 1)
            {
                tablename = cl.getName().toUpperCase();
            }
            List<String> columnDefs = new ArrayList<String>();
            for (Field field: cl.getDeclaredFields())
            {
                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().toLowerCase();
                    }
                    else
                    {
                        columnName = sInt.name();
                    }
                    columnDefs.add(columnName + " INT" + getConstraints(sInt.constraints()));;
                }

                if (anns[0] instanceof SQLString)
                {
                    SQLString sqlString = (SQLString)anns[0];
                    if (sqlString.name().length() < 1)
                    {
                        columnName = field.getName().toUpperCase();
                    }
                    else
                    {
                        columnName = sqlString.name();
                    }
                    columnDefs.add(columnName + " VarChar(" + sqlString.value() + ")" + getConstraints(sqlString.constrants()));
                }
            }

            StringBuilder createCommmand = new StringBuilder("Create table" + tablename + "(");
            for (String columnDef:  columnDefs)
            {
                createCommmand.append("\n     "  + columnDef + ",");
            }
            String tablecreats = createCommmand.substring(0, createCommmand.length() - 1) + ");";
            System.out.println("Table create Sql for" + className + "is:\n" + tablecreats);
        }
    }

    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;
    }
}

TableCreator类主要用来对注解进行解析,通过传进的带解析的类名,Class.forName(className) 生成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值