关于java的注解

     1.0

   @Target(ElementType.METHOD)
   @Retention(RetentionPolicy.RUNTIME)
   public @interface UseCase {
       public int id();
       public String description() default "no description";
   }
     上面的代码就是一个简单注解示例。可以看到他的上面还有两个注解,如果全部算上,其实还有两个,@Document和@Inherited。他们各自的使用方式和作用如下

@Target表示注解可以使用的位置,值为java中的枚举类ElementType。一般使用下面几个
a. CONSTRUCTOR 构造器的声明
b. Field :域声明(这个域就是值得类里面的各个创建的属性)
c. LOCAL_VARIABLE:局部变量声明
d. METHOD :方法声明
e. PARAMETER : 方法声明
f. TYPE : 类,接口或者枚举类(enum)的声明
@Retention表示在什么级别保存该注解信息,可选的RetentionPolicy参数包括:
a. SOURCE : 注解将被编译器丢弃
b. CLASS :注解将在class文件中用,单被VM丢弃
c. RUNTIME : VM也会保留注解,所以能够通过反射机制读取注解信息
@Document注解将被包含在doc文件中
@Inherited允许子类继承父类中的注解

   注解可用的元素有String,所有的基本类型(int,float,boolean),Class,enum,Annotation 以及他们的数组。也就是说不能在注解中使用自己定义的类或者大多数的java类。

  下面是个简单的使用注解获取反射信息的dbsql生成String的类:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
      String name() default "";
}
@DBTable(name = "MEMBER")
public class Member {
    @SQLString(30)
    String firstName;
    @SQLString(50)
    @SQLInteger
    String lastName;
    @SQLInteger
    Integer age;
    @SQLString(value=30,constraints = @Constraints(primaryKey = true))
    String handle;

    static int memberCount;

    public String getHandle(){
        return handle;
    }
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setHandle(String handle) {
        this.handle = handle;
    }

    public static int getMemberCount() {
        return memberCount;
    }

    public static void setMemberCount(int memberCount) {
        Member.memberCount = memberCount;
    }

}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
    int value() default 0;
    String name() default "";
    Constraints constraints() default @Constraints();

}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
    String name() default "";
    Constraints constraints() default @Constraints;
}


public class TableCreator {
    public static void main(String agrs[]) throws ClassNotFoundException {
      //通过名字得到Member的class文件,用于反射获取类中的属性(域),这里的类名(Member)一定要加上包名,不然找不到
      Class<?> clazz=Class.forName("Member");
        DBTable dbTable=clazz.getAnnotation(DBTable.class);
        if(dbTable==null){
            System.out.println("请输入正确的带注解的类");
            System.exit(0);
        }
        String tableName=dbTable.name();
        List<String> colNumbers=new ArrayList<String>();
      //将获取到的域进行处理
        for(Field field:clazz.getDeclaredFields()){
            String columnName=null;
            //感觉注解最后是用的代理实现的
            Annotation[] annotations=field.getDeclaredAnnotations();
            if(annotations.length<1){
                System.out.println("当前没有注解");
               // System.exit(0);
            }else {//因为只有一个注解,所以用0,多个可以多个处理
                if (annotations[0] instanceof SQLString) {
                       SQLString sString = (SQLString) annotations[0];
                    if (sString.name().length() < 1) {
                        columnName = field.getName().toUpperCase();
                    } else {
                        columnName = sString.name();
                    }
                    colNumbers.add(columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()));
                }
                if (annotations[0] instanceof SQLInteger) {
                    SQLInteger sSQLInteger = (SQLInteger) annotations[0];
                    if (sSQLInteger.name().length() < 1) {
                        columnName = field.getName().toUpperCase();//获取当前属性名称
                    } else {
                        columnName = sSQLInteger.name();

                    }
                    colNumbers.add(columnName + " INT " + getConstraints(sSQLInteger.constraints()));
                }
            }

        }
        StringBuilder sb=new StringBuilder("CREATE TABLE "+tableName+" (");
        for(String col:colNumbers){
            sb.append("\n  "+col+",");
        }
        String table=sb.substring(0,sb.length()-1)+" );";
        System.out.println(table);
    }
    private static String getConstraints(Constraints constraints){
        String cs="";
        if(!constraints.allNull()){
            cs+=" NOT Null";
        }
        if(constraints.primaryKey()){
            cs+=" PRIMARY KEY";
        }
        if(constraints.unique()){
            cs+=" UNIQUE";
        }
        return cs;
    }
}

最后运行的结果为:

当前没有注解   

CREATE TABLE MEMBER (
  FIRSTNAME VARCHAR(30),
  LASTNAME VARCHAR(50),
  AGE INT ,
  HANDLE VARCHAR(30) PRIMARY KEY );


因为memberCount没有注解,所以会进入打印的方法中,其他带注解的都成功被反射出来。

感觉这是个后台自动生成sql查询语句的办法,以后抽时间写一个



最后,以上的内容主要来自于java编程思想和我的一些注解,如有不对的地方,忘指正。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值