因为一个表对应一个java类,如果java类多了,一个一个创建表太消耗时间了,同时也想造下轮子。加深下对反射和注解的使用
反射和注解把java一切皆对象的思想完全的体现了出来,同时也给java提供了强大的动态性。
主要进行工作的类,可以在里面加上jdbc,就可以实现自动创建表了。
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class AutoCreatTable {
private String pre = "CREATE TABLE ";
private String bodyPre = "(";
private String bodySub = ")";
private String NN = "NOT NULL";
private String N = "NULL";
private String idAuto = "AUTO_INCREMENT";
private String PRIMARY_KEY = "PRIMARY KEY";
private String ENGINE = "ENGINE=InnoDB";
private String[] havaLength = {"varchar","char","bit"};
enum rowType {
Int("int"),Char("char"),Strings("varchar") ;
String type;
rowType(String type) {
this.type = type;
}
}
public void creatTable(Class<?> table){
String[] colum;
ArrayList<String> pkey = new ArrayList<>();
int i = 0;
//获取注解
Table tableAnnotation = table.getAnnotation(Table.class);
if (tableAnnotation == null){
System.out.println("没使用Table注解");
return;
}
String creatSQL;
creatSQL = pre + tableAnnotation.name();
System.out.println(creatSQL);
Field field[] = table.getDeclaredFields();
colum = new String[field.length];
for (Field f:field) {
f.setAccessible(true);
Annotation[] annotations = f.getDeclaredAnnotations();
String name = null;
String type = null;
String size = null;
boolean isiD =false;
boolean isN = true;
if (annotations.length == 0){
return;
}
for (Annotation a:annotations) {
if (a instanceof Column){
if (((Column) a).name().equals("")){
typeBean tb = getField(f);
name = tb.name;
}else {
name = ((Column) a).name();
}
if (((Column) a).type().equals("")){
typeBean tb = getField(f);
type = tb.type;
}else {
type = ((Column) a).type();
}
if (((Column) a).length().equals("")){
size = "255";
}else {
size = ((Column) a).length();
}
isN = ((Column) a).okNull();
}
if (a instanceof Id){
isiD = true;
pkey.add(f.getName());
}
}
String row = creatRow(name,type,isN,isiD,size);
colum[i] = row;
i = i+1;
System.out.println(row);
}
StringBuilder body = new StringBuilder(String.join(",",colum)) ;
System.out.println(body);
String[] ks = new String[pkey.size()];
pkey.toArray(ks);
body.append(",").append(setPRIMARY_KEY(ks)) ;
creatSQL = creatSQL+"(" + body + ")"+";";
System.out.println(creatSQL);
}
String creatRow(String name,String type,boolean isnull,boolean isID,String size){
StringBuilder row = new StringBuilder();
row.append(name).append(" ");
//设置类型
if (size!=null){
if (haveLength(type)){
row.append(setSize(type,size)).append(" ");
}else {
row.append(type).append(" ");
}
}else {
row.append(type).append(" ");
}
//设置字段是否为空
if (isnull){
//值为true
row.append(N).append(" ");
}else {
row.append(NN).append(" ");
}
//设置id
if (isID){
row.append(idAuto).append(" ");
}
return row.toString();
}
String setPRIMARY_KEY(String ...field){
String fields = String.join(",",field);
return this.PRIMARY_KEY+bodyPre+fields+bodySub;
}
String setSize(String type,String size){
return type+bodyPre+size+bodySub;
}
typeBean getField(Field field){
typeBean tb = new typeBean();
tb.name = field.getName();
tb.setType(field.getType().toString());
return tb;
}
boolean haveLength(String type){
Set<String> set = new HashSet<>(Arrays.asList(havaLength));
return set.contains(type);
}
public void catTable(Class<?>...classes){
for (Class c:classes
) {
creatTable(c);
}
}
class typeBean{
String name;
String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
if (type.lastIndexOf("String")!=-1){
type ="varchar" ;
}
this.type = type;
}
}
}
注解:Column 用于标记表的列,也就是类的字段
代码实现:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String name() default "";
String length() default "";
String type() default "";
boolean okNull() default false;
}
主键注解,用于标记主键
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
}
表注解,用于标识表,和包扫描配合在一起,就可以实现自动创建、
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String name();
}
测试一下:定义一个类
@Table(name = "testName")
public class User {
@Id
@Column
int uid;
@Column
String name;
@Column(name = "pass",type = "int",okNull = true)
String pass;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
测试代码:
@Test
public void testAutoCreatTable(){
AutoCreatTable creatTable = new AutoCreatTable();
creatTable.catTable(User.class);
}
测试结果:生成的sql语句
看上去没什么大问题。可以进行很多拓展,比如支持所有的mysql类型,支持外键等,还可以自动生成简单crud等。但这样的轮子已经有了,就不重复造了。
标签:反射,java,String,生成,MySQL,type,public,append,name From: https://www.cnblogs.com/aoCat/p/17317582.html