我但愿经过注解来生成一个实体类对应表的的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); } }