我但願經過註解來生成一個實體類對應表的的SQL語句。因此寫了兩個註解類,一個Table標識要生成SQL的實體類,一個Column用來標識要映射到表的字段。一個簡單的實體類User和一個註解的工具類GenerateTableUtil。代碼只是爲了更加了解註解。因此處理註解的工具類GenerateTableUtil很是的不完善,若是你感興趣能夠完善一下註解工具類貼出來分享給你們。java
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 Table { String value() default ""; }
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 Column { //通常只有一個值,就使用value。這樣在使用註解時就能夠像@Column("id")這樣使用,不然若是咱們使用id就要@Column(id="id") //通常能夠使用default加上默認值,這裏就默認爲空,咱們能夠在處理註解的時候把字段的名字當作value的值 String value() default ""; }
@Table public class User { @Column private int id; @Column private String name; @Column private String phone; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
import java.lang.reflect.Field; import java.sql.Date; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class GenerateTableUtil { public static void generateSQL(Class<?> clazz) { Table tableAnnotation = null; if(clazz.isAnnotationPresent(Table.class))//檢查類上是否有Table註解 tableAnnotation = clazz.getAnnotation(Table.class); else return; String tableName = tableAnnotation.value(); if(null ==tableName || tableName.length()==0) tableName = clazz.getSimpleName().toUpperCase(); Field[] fields = clazz.getDeclaredFields(); Map<String,String> cols = new HashMap<String,String>(); //檢查有Column註解的字段,若是有則映射到數據庫的字段上 for(Field field:fields) { Column columnAnnotation = null; if(field.isAnnotationPresent(Column.class)) { columnAnnotation = field.getAnnotation(Column.class); String colName = columnAnnotation.value(); if(null == colName || colName.length()==0) colName = field.getName().toUpperCase(); Class<?> type = field.getType(); String jdbcType = "VARCHAR(20)"; try { //最好不要在這裏捕獲異常,由於字段轉換已經出錯了。這裏簡化了處理若是類型不支持就直接使用默認值 jdbcType = getJdbcType(type); } catch (Exception e) { e.printStackTrace(); } cols.put(colName, jdbcType); } } System.out.println(joinSQL(tableName,cols)); } /** * 沒有判斷全部的數據類型,映射關係不完整 * @param type java的類型的class * @return 數據庫的類型 * @throws Exception 沒有構造本身的異常 */ private static String getJdbcType(Class<?> type) throws Exception { if(type.isAssignableFrom(int.class)||type.isAssignableFrom(Integer.class)) return "INT"; if(type.isAssignableFrom(String.class)) return "VARCHAR(20)"; //字符串數據的長度默認爲20,不可取只是測試 if(type.isAssignableFrom(char.class)) return "CHAR(20)"; if(type.isAssignableFrom(Date.class)) return "DATETIME"; if(type.isAssignableFrom(long.class)||type.isAssignableFrom(Long.class)) return "BIGINT"; if(type.isAssignableFrom(float.class)||type.isAssignableFrom(Float.class)) return "FLOAT"; if(type.isAssignableFrom(double.class)||type.isAssignableFrom(Double.class)) return "DOUBLE"; else throw new Exception("數據類型不支持"); } /** * 根據名字和字段生成SQL語句 * @param tableName * @param fields * @return */ private static String joinSQL(String tableName,Map<String,String> fields) { StringBuffer sb = new StringBuffer("CREATE TABLE "); sb.append(tableName); sb.append('('); Set<Entry<String,String>> entrySet = fields.entrySet(); for(Entry<String, String> entry:entrySet) { sb.append(entry.getKey()); sb.append(" "); sb.append(entry.getValue()); sb.append(','); } sb.replace(sb.length()-1, sb.length(), ")"); return sb.toString(); } public static void main(String[] args) { generateSQL(User.class); } }