`

JAVA 注解(Annotation) ,模拟自动创建表

 
阅读更多

hibernate 里面通过注解,映射等手段,可以自动生成表,现在模拟实现。随便学学注解如何使用。

首先,我们要定义几个注解:

Table 用于定义表名字,类型使用Type

 

 Java代码  收藏代码

  1. import java.lang.annotation.ElementType;  
  2. import java.lang.annotation.Retention;  
  3. import java.lang.annotation.RetentionPolicy;  
  4. import java.lang.annotation.Target;  
  5.   
  6. @Target(ElementType.TYPE)  
  7. @Retention(RetentionPolicy.RUNTIME)  
  8. public @interface Table {  
  9.     // 表名  
  10.     String name() default "";  
  11. }  

 

Types,定义一下常用的类型,这里我写得比较乱,也可以使用 枚举  等其他方法,方便使用

Java代码  收藏代码
  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3.   
  4. public class Types {  
  5.     // 自己定义的一些基本类型,和数据对应就行了,就是组成字符串  
  6.     // 这是临时的办法,需要大家从新设计  
  7.     public static final String  VARCHAR = "VARCHAR";  
  8.     public static final String INT = "INT";  
  9.     public static final String BOOLEAN = "BOOLEAN";  
  10.   
  11.     // 默认长度,和数据库对应  
  12.     public static final int STRING_LENGTH =32;  
  13.     public static final int INT_LENGTH = 10;  
  14.       
  15.     // 将类型 已经默认长度,放入集合  
  16.     public static Map<String,Integer> map = new HashMap();  
  17.     static{  
  18.         map.put(VARCHAR, STRING_LENGTH);  
  19.         map.put(INT, INT_LENGTH);  
  20.         map.put(BOOLEAN, 0);  
  21.     }  
  22.       
  23.     public static String getType(String type,int length){  
  24.         if(type == null){  
  25.             throw new RuntimeException("Not recognized the type  :"+type);  
  26.         }  
  27.         // 防止boolean 这类型  
  28.         if( length > 0){  
  29.             return type+"("+length+")";  
  30.         }  
  31.         return type;  
  32.     }  
  33.       
  34.     public static String getString(){  
  35.         return getStirng(VARCHAR, STRING_LENGTH);  
  36.     }  
  37.     public static String getString(int length){  
  38.         return getStirng(VARCHAR, length);  
  39.     }  
  40.       
  41.     public static String getInt(){  
  42.         return getStirng(INT, INT_LENGTH);  
  43.     }  
  44.     public static String getInt(int length){  
  45.         return getStirng(INT, length);  
  46.     }  
  47.     public static String getBoolean(){  
  48.         return BOOLEAN;  
  49.     }  
  50.       
  51.     private static String getStirng(String str,int length){  
  52.         return str+"("+length+")";  
  53.     }  
  54. }  

 

这是建表的一些约束条件,只写普通的,可以自己添加

Java代码  收藏代码
  1. import java.lang.annotation.ElementType;  
  2. import java.lang.annotation.Retention;  
  3. import java.lang.annotation.RetentionPolicy;  
  4. import java.lang.annotation.Target;  
  5.   
  6. @Target(ElementType.FIELD)  
  7. @Retention(RetentionPolicy.RUNTIME)  
  8. public @interface Constraints{  
  9.         // 是否主键,是否为空 等  
  10.     boolean primaryKey() default false;  
  11.     boolean allowNull() default true;  
  12.     boolean unique() default false;  
  13. }  

 Column 是 对映实体Bean 

 

Java代码  收藏代码
  1. import java.lang.annotation.ElementType;  
  2. import java.lang.annotation.Retention;  
  3. import java.lang.annotation.RetentionPolicy;  
  4. import java.lang.annotation.Target;  
  5.   
  6. @Target(ElementType.FIELD)  
  7. @Retention(RetentionPolicy.RUNTIME)  
  8. public @interface Column {  
  9.     // 名字  
  10.     String name() default "";  
  11.     // 长度  
  12.     int length() default 0;  
  13.     // 类型  
  14.     String type();  
  15.     // 约束,这里可以使用其他注解类型。  
  16.     Constraints  constraints() default @Constraints;  
  17. }  

 

下面看我们的实体

 

Java代码  收藏代码
  1. @Table(name="TestTable")  
  2. @SuppressWarnings("unused")  
  3. public class TestTable {  
  4.     // 指定了列名字,约束为 主键,长度 以及类型  
  5.     @Column(name="id",constraints=@Constraints(primaryKey=true),length=15, type = Types.INT)  
  6.     private int id;  
  7.       
  8.     // 列名 类型,如果都没有,只能使用默认的,也可以在后面处理类 里面 定义  
  9.     @Column(name="name", type = Types.VARCHAR)  
  10.     private String name;  
  11.       
  12.     @Column(type = Types.BOOLEAN)  
  13.     private Boolean sex;  
  14. }  

 

基本工作完成了,下面就是如果完成解析,获得我们需要的SQL:

Java代码  收藏代码
  1. import java.lang.annotation.Annotation;  
  2. import java.lang.reflect.Field;  
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6.   
  7. public class CrateTable {  
  8.       
  9.     public static void main(String[] args) {  
  10.         // 类路径  
  11.         System.out.println(getCreateSQL("com.annotation.TestTable"));  
  12.     }  
  13.       
  14.     @SuppressWarnings("unused")  
  15.     public static String getCreateSQL(String className){  
  16.         try {  
  17.             // 加载类  
  18.             Class<?> c = Class.forName(className);  
  19.             // 获得指定类型的注解对象  
  20.             Table table = c.getAnnotation(Table.class);   
  21.             if(table == null){  
  22.                 System.out.println("No Table annotation in class "+ className);  
  23.                 return null;  
  24.             }  
  25.             String tableName = table.name();  
  26.             if(tableName.length() == 0){  
  27.                 // 如果没指定长度, 可以默认以类的名字 命名表名  
  28.                 tableName = c.getName().toUpperCase();  
  29.             }  
  30.             List<String> columns = new ArrayList<String>();  
  31.               
  32.             // 遍历所有字段  
  33.             for(Field field : c.getDeclaredFields()){  
  34.                 String columnName = null;  
  35.                 String columnType = null;  
  36.                 // 获得每个字段上的注解信息,这里不需要继承的注解  
  37.                 // 还有其他方法,具体可以去看API  
  38.                 Annotation[] anns = field.getDeclaredAnnotations();  
  39.                 if(anns.length == 0){  
  40.                     // 如果该字段没有注解,表示这个字段,不需要生成  
  41.                     continue;  
  42.                 }else{  
  43.                     // 获得该字段的注解信息,默认这设置的column注解信息  
  44.                     Column col = (Column) anns[0];  
  45.                     // 获得建表 语句  字符串  
  46.                     String name = col.name();  
  47.                     String type = col.type();  
  48.                     Integer length = col.length();  
  49.                     String constraint = getConstraints(col.constraints());  
  50.                     if(name.length() == 0){  
  51.                         // 获得默认字段名  
  52.                         columnName = field.getName();  
  53.                     }else{  
  54.                         columnName = name;  
  55.                     }  
  56.                     if(type.length() == 0){  
  57.                         // 获得默认类型  
  58.                         columnType = field.getType().toString();  
  59.                     }else{  
  60.                         columnType = type;  
  61.                     }  
  62.                     if(length == 0){  
  63.                         // 获取默认长度  
  64.                         length = Types.map.get(type);  
  65.                         if(length == null){  
  66.                             throw new RuntimeException("Type cant't be solved :"+type);  
  67.                         }  
  68.                     }  
  69.                     type = Types.getType(type,length);  
  70.                     columns.add(columnName + " "+ type+constraint);  
  71.                 }  
  72.             }  
  73.             if(columns.size() == 0){  
  74.                 throw new RuntimeException("There is no field in "+className);  
  75.             }  
  76.             StringBuilder createCommand = new StringBuilder("CREATE TABLE "+tableName +" (");  
  77.             for(String column : columns){  
  78.                 createCommand.append("\n "+column +" ,");  
  79.             }  
  80.             String createTable = createCommand.substring(0,createCommand.length()-1)+" \n );";  
  81.             return createTable;  
  82.               
  83.         } catch (ClassNotFoundException e) {  
  84.             e.printStackTrace();  
  85.         }  
  86.         return null;  
  87.     }  
  88.       
  89.     /** 
  90.      * 获得约束条件 
  91.      * @param con 
  92.      * @return 
  93.      */  
  94.     private static String getConstraints(Constraints con){  
  95.         String constraints = "";  
  96.         if(!con.allowNull()){  
  97.             constraints += " NOT NULL";  
  98.         }  
  99.         if(con.primaryKey()){  
  100.             constraints += " PRIMARY KEY";  
  101.         }  
  102.         if(con.unique()){  
  103.             constraints += " UNIQUE ";  
  104.         }  
  105.         return constraints;  
  106.     }  
  107.       
  108.     /** 
  109.      * 获得所需要的字段 
  110.      * @param fields 
  111.      * @return 
  112.      */  
  113.     public static List<Field> getNeedField(Field[] fields){  
  114.         List<Field> allFileds = new ArrayList<Field>();  
  115.         for(Field field : fields){  
  116.             // 获得每个字段上的注解信息,这里不需要继承的注解  
  117.             Annotation[] anns = field.getDeclaredAnnotations();  
  118.             if(anns.length != 0){  
  119.                 // 如果该字段没有注解,表示这个字段,不需要生成  
  120.                 allFileds.add(field);  
  121.             }  
  122.         }  
  123.         return allFileds;  
  124.     }  
  125. }  

 

上面用了一下反射的功能,有些比较死板,要灵活构建,需要从写。可以进行测试,获得的SQL,是否可以生成表,当然也可以移动到xml 配置文件里面,这里我暂时不写了,先看测试。

其实只需要打印出SQL,看看是否正确就行了。

下面的方法, 用了JDBC连接。详情请看:http://greemranqq.iteye.com/admin/blogs/1830200

 

Java代码  收藏代码
  1. /** 
  2.  * 执行SQL 
  3.  * @param sql 
  4.  */  
  5. public static void executeSql(String sql){  
  6.     conn = ConnectionUtil.getConnection();  
  7.     try {  
  8.         PreparedStatement ps = conn.prepareStatement(sql);  
  9.         ps.execute();  
  10.     } catch (SQLException e) {  
  11.         e.printStackTrace();  
  12.     }finally{  
  13.         ConnectionUtil.colse(conn);  
  14.     }  
  15. }  
  16.   
  17. public static void main(String[] args) {  
  18.     String sql = CrateTable.getCreateSQL("com.annotation.TestTable");  
  19.     System.out.println(sql);  
  20.     executeSql(sql);  
  21.       
  22. }  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics