Java 注解入门 自动生成SQL语句

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Java 注解入门 自动生成SQL语句脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

引言

在用hibernate的时候发现idea能自动生成JavaBean,同时带有一些注解,这引起了我的好奇。当在学习AndROId的时候,我发现XUtils这个工具包中的DBUtils也能够使用类似hibernate的注解。于是乎在java编程思想中找了找有关注解的用法。

一 注解定义

注解(也称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。注解来于C#之类的其他语言。

注解的语法比较简单,除了@符号外,它与java的固有语法一致。javaSE5中内置了三种注解:

@override:定义覆盖超类,当覆写对应不上被覆盖的方法,编译器发出错误提示

@DePRecated:当使用了该注解,即表示这个方法已经不推荐被使用。

@SupPressWarnings:关闭不当的编译器警告。

二 基本语法

我们使用自定义的注解对一个方法进行注解:

public class testable{     public void execute()     {         System.out.println("execute...");     }     @WETest     void taskStart()     {         execute();     } }

在上边的代码中,我们对taskStart方法使用了注解,接下来我们对WETest注解进行定义:

import java.lang.annotation.*;   @Target(ElementTyPE.METHOD) @Retention(Retentionpolicy.RUNTIME) public @interface WETest{}

三 定义注解

我们给上边的注解添加一些内容:

import java.lang.annotation.*;   @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface WETest{     public int id();     public String Notes() default "there is no Notes"; }

同样,我们对Testable类使用最新的注解:

public class Testable{     @WETest(id=666)     public void execute()     {         System.out.println("execute...");     }     @WETest(id=666,Notes="this is a method")     void taskStart()     {         execute();     } }

注解就是这么使用的,当注解内容没有填写时,他会使用默认的值,如execute方法,他没有定义Notes,那么Notes默认值为"there is no Notes"。

四 元注解

我们看到注解上边有两行内容,它们是元注解,专门对注解的解释。元注解一共有四种,分别是:

@Target:表示该注解可以用到哪些地方,ElementType,CONSTRUCTOR构造器声明,FIELD域声明(包括enum实例),LOCAL_VARIABLE局部变量声明,METHOD方法,PACKAGE包,PARamETER参数,TYPE类、接口或enum。

@Retention:表示需要在什么级别上使用,RetentionPolicy,SOURCE注解会被编译器丢掉,CLASS在class文件中可用会被VM抛弃,RUNTIME在VM运行期也会保留可以通过反射获取注解信息。

@Documented:将注解包含在Javadoc中。

@InherITed:允许子类继承父类中的注解。

五 通过注解反射生成SQL语句

接下来,我用一个例子来解释注解的作用。先编写一些注解定义:

//DBTable.java            用来生成数据表 package annotations;   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 ""; }   //Constraints.java        用来定义约束项 package annotations;   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 Constraints {     boolean Primarykey() default false;     boolean allownull() default true; }   //PrimaryKey.java        将Constraints中的primarykey定义为真,表示为主键 package annotations;   import java.lang.annotation.*;   @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface PrimaryKey {     Constraints constraints() default @Constraints(primarykey = true); }   //SQLInteger.java         定义列的类型 package annotations;   import java.lang.annotation.*;   @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface SQLInteger {     String name() default "";     Constraints constraints() default @Constraints; }   //SQLString.java        定义列的类型 package annotations;   import java.lang.annotation.*;     @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface SQLString {     int value() default 64;     String name() default "";     Constraints constraints() default @Constraints; }    接下来写一个javabean,使用上述注解:   //User.java import annotations.Constraints; import annotations.DBTable; import annotations.SQLInteger; import annotations.SQLString;   @DBTable(name="user") public class User {     @SQLInteger(name="id",constraints = @Constraints(primarykey=true))     public Integer id;     @SQLString(value=30)     public String name;     @SQLString(name="passwd",constraints=@Constraints(allownull=false))     public String password;           /*可以不用     public void setId(Integer id) {         this.id = id;     }     public void setName(String name) {         this.name = name;     }     public void setPassword(String password) {         this.password = password;     }     public Integer getId() {         return id;     }     public String getName() {         return name;     }     public String getPassword() {         return password;     }*/ }

我们看到注解中可以使用注解,在SQLInteger中我们使用了Constraints注解。

接下来我们写一个注解处理器

//Test.java import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Scanner;   import annotations.Constraints; import annotations.DBTable; import annotations.SQLInteger; import annotations.SQLString;   public class Test {           public static String getConstraints(Constraints con)     {         String constraints = "";         if(!con.allownull())         {             constraints +=" NOT NULL";         }         if(con.primarykey())         {             constraints += " PRIMARY KEY";         }         return constraints;     }       public static void main(String[] args) throws ClassNotFoundException {         Scanner s = new Scanner(System.in);         String name = s.next();                                    //从控制台输入一个类名,我们输入User即可         Class<?> cl = Class.forName(name);                         //加载类,如果该类不在默认路径底下,会报 java.lang.ClassNotFoundException         DBTable dbTable = cl.getAnnotation(DBTable.class);         //从User类中获取DBTable注解         if(dbTable == null){                                       //如果没有DBTable注解,则直接返回,我们写了,当然有             return;         }         String tableName = (dbTable.name().length()<1)?cl.getName():dbTable.name();//获取表的名字,如果没有在DBTable中定义,则获取类名作为Table的名字         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];                 columnName = (sInt.name().length()<1)?field.getName():sInt.name();//获取列名称与获取表名一样                 columnDefs.add(columnName+" INT"+getConstraints(sInt.constraints()));//使用一个方法,自己写的getConstraints(Constraints constraints)获取列定义             }             if(anns[0] instanceof SQLString)             {                 SQLString sStr = (SQLString)anns[0];                 columnName = (sStr.name().length()<1)?field.getName().toUpperCase():sStr.name();                 columnDefs.add(columnName + " VArchAR("+sStr.value()+")"+getConstraints(sStr.constraints()));             }         }         StringBuilder createCommand = new StringBuilder("CREATE TABLE "+tableName+"(");         for(String columnDef :columnDefs)         {             createCommand.append("n    "+columnDef+",");         }         String tableCreate = createCommand.substring(0,createCommand.length()-1)+"n);";         System.out.println(tableCreate);                        //打印出来     }   }

我们可以采用上述方法动态的处理一些数据,例如创建数据表。

六 总结

注意:注解不支持继承例如 extends @xxx。      注解的default默认值不可以为null 

使用注解可以减少对XMl等外部文件的依赖,使得对类的定义可以在一处实现,避免了一个类两处定义的麻烦。spring和hibernate就采用的这样的方法。
更多文章http://blog.gavinzh.com

脚本宝典总结

以上是脚本宝典为你收集整理的Java 注解入门 自动生成SQL语句全部内容,希望文章能够帮你解决Java 注解入门 自动生成SQL语句所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。