第一步:创建实体类
定义一个实体类,在字段上使用knife4j的接口文档注解@ApiModelProperty注解指定字段名。
package cn.edu.sgu.www.mhxysy.entity.role;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
/**
* 黑名单
* @author heyunlin
* @version 1.0
*/
@Data
@ApiModel
@TableName("black_list")
public class BlackList implements Serializable {
private static final long serialVersionUID = 18L;
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "ID")
private Integer id;
/**
* 角色ID
*/
@ApiModelProperty(value = "角色ID")
private String roleId;
/**
* 角色名
*/
@ApiModelProperty(value = "角色名")
private String roleName;
/**
* 拉黑理由
*/
@ApiModelProperty(value = "拉黑理由")
private String reason;
/**
* 拉黑时间
*/
@ApiModelProperty(value = "拉黑时间")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private LocalDate operateTime;
}
第二步:创建一个类保存表的信息
package cn.edu.sgu.www.mhxysy.entity.other;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author heyunlin
* @version 1.0
*/
@Data
@ApiModel
public class ClassProperty implements Serializable {
private static final long serialVersionUID = 18L;
/**
* 字段名称
*/
@ApiModelProperty(value = "表名称")
private String name;
/**
* 字段类型
*/
@ApiModelProperty(value = "字段类型")
private String dataType;
/**
* 字段注释
*/
@ApiModelProperty(value = "字段注释")
private String comment;
}
第三步:Java和数据库的类型映射
创建Java数据类型和表字段类型的对应关系
package cn.edu.sgu.www.mhxysy.base;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Java数据类型-字段类型
* @author heyunlin
* @version 1.0
*/
public class FieldTypes {
/**
* 创建一个map,保存Java数据类型和数据库字段类型的映射关系
*/
private static final Map<Class<?>, String> CLASS_STRING_MAP = new HashMap<>();
static {
CLASS_STRING_MAP.put(Integer.class, "int(11) unsigned");
CLASS_STRING_MAP.put(Date.class, "date");
CLASS_STRING_MAP.put(LocalDate.class, "date");
CLASS_STRING_MAP.put(LocalDateTime.class, "datetime");
CLASS_STRING_MAP.put(String.class, "varchar(255)");
}
public static String getType(Class<?> propertyType) {
return CLASS_STRING_MAP.get(propertyType);
}
}
第四步:使用反射生成创建表的SQL语句
package cn.edu.sgu.www.mhxysy;
import cn.edu.sgu.www.mhxysy.base.FieldTypes;
import cn.edu.sgu.www.mhxysy.entity.other.ClassProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* springboot测试类
* @author heyunlin
* @version 1.0
*/
@SpringBootTest
class MhxysyTests {
@Test
void generateTableCreatementSQL() throws ClassNotFoundException {
String className = "cn.edu.sgu.www.mhxysy.entity.role.BlackList";
/*
* 表名
*/
String tableName = toLower(className);
Class<?> type = Class.forName(className);
// 获取类的所有字段信息
Field[] fields = type.getDeclaredFields();
List<ClassProperty> list = new ArrayList<>(fields.length);
for (Field field : fields) {
ClassProperty classProperty = new ClassProperty();
// 字段名
if (field.isAnnotationPresent(TableField.class)) {
TableField tableField = field.getAnnotation(TableField.class);
classProperty.setName(tableField.value());
} else {
classProperty.setName(toLower(field.getName()));
}
// 字段类型
String fieldType = FieldTypes.getType(field.getType());
classProperty.setDataType(fieldType);
// 字段注释
if (field.isAnnotationPresent(ApiModelProperty.class)) {
ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
classProperty.setComment(apiModelProperty.value());
}
list.add(classProperty);
}
// 开始拼接SQL语句
StringBuilder sb = new StringBuilder();
sb.append("create table ").append(tableName).append("(");
for (ClassProperty classProperty : list) {
if (!"serialVersionUID".equals(classProperty.getName())) {
sb.append(classProperty.getName()).append(" ");
sb.append(classProperty.getDataType()).append(" ");
if ("id".equals(classProperty.getName())) {
sb.append("primary key ");
if (classProperty.getDataType().contains("int")) {
sb.append("auto_increment ");
}
}
sb.append("comment '").append(classProperty.getComment()).append("', ");
}
}
String sql = sb.substring(0, sb.length() - 2) + ")";
System.out.println(sql);
}
/**
* 驼峰命名转下划线命名
* @param str 待转换的字符串
* @return String
*/
public static String toLower(String str) {
// 小写和大写紧挨一起的地方加上分隔符_,然后全部转为小写
str = str.replaceAll("([a-z])([A-Z])", "$1_$2");
return str.toLowerCase();
}
}