package cn.x;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Scanner;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.reflections.Reflections;
import cn.hutool.core.util.StrUtil;
import cn.x.BaseDO;
/**
* 根据实体类生成mysql表CREATE语句
*/
public class DO2TableGenerateTest {
public static final String basePackage = "cn.x";
public static final Class<?> clazzBase = BaseDO.class;
public static void main(String[] args) throws InterruptedException {
// 需要mysql表的多个实体类
Reflections f = new Reflections(basePackage, new Scanner[0]);
Set<Class<?>> clazzs = f.getTypesAnnotatedWith(TableName.class);
StringBuilder sqlCombined = new StringBuilder(); // 合并后的可执行sql
// 循环生成多个sql执行语句
for (Class<?> clazz : clazzs) {
String className = clazz.getSimpleName();
// 去除实体类名称中多余的字符
//表名称 驼峰命名转小写下划线分隔 例如:ErpCustomer--->erp_customer
String classNameTaken = StrUtil.endWith(className, "DO") ?
StrUtil.sub(className, 0, className.length() - 2) :
className;
TableName annotation = clazz.getAnnotation(TableName.class);
String tableName =
annotation.value() == null ? StrUtil.toUnderlineCase(classNameTaken) : annotation.value();
StringBuilder sql = tableGeneratedCreateUtil(tableName, "", clazz); // 可执行sql
sqlCombined.append("\n-- =======================================\n");
sqlCombined.append(sql);
}
// 打印执行语句
System.out.println(sqlCombined);
;
}
/**
* 生成mysql的create语句
*
* @param tableName 表名称
* @param tableComment 表备注
* @param clazz 实体类
*/
static StringBuilder tableGeneratedCreateUtil(String tableName, String tableComment, Class<?> clazz) {
StringBuilder sql = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " (\n");
try {
Field[] fields = clazz.getDeclaredFields();
String key = null;
for (Field field : fields) {
boolean isKey = false;
// 表字段
String columnName = null; // name修改为表字段格式
TableField tableField = field.getAnnotation(TableField.class);
if (tableField != null && StringUtils.isNotBlank(tableField.value())) {
columnName = tableField.value();
} else {
columnName = StrUtil.toUnderlineCase(field.getName());
}
if (key == null) {
TableId tableId = field.getAnnotation(TableId.class);
if (tableId != null) {
key = columnName;
isKey = true;
}
}
// 数据类型
String columnType = fieldTypeConvDataTypeUtil(field.getType());
sql.append(" `" + columnName + "` " + columnType);
if (isKey) {
sql.append(" auto_increment ");
}
sql.append(" COMMENT '" + field.getName() + "',\n");
}
// 拼接通用字段 (若不需要则可注释掉)
StringBuilder baseDoSql = baseDoSqlGenerated();
sql.append(baseDoSql);
// 设置主键id
sql.append("PRIMARY KEY(`" + key + "`)");
sql.append("\n)");
// 添加表注释(如果数据库支持)
if (!tableComment.isEmpty()) {
sql.append(" COMMENT='" + tableComment + "';");
} else {
sql.append(";");
}
} catch (Exception e) {
e.printStackTrace();
}
return sql;
}
/**
* 通用字段sql
*
* @return baseDoSql 拼接目标表生成sql中的部分通用字段sql
*/
static StringBuilder baseDoSqlGenerated() {
// 通用字段所需的实体类BaseDO.class
if (clazzBase == null) {
return new StringBuilder();
}
Field[] fields = clazzBase.getDeclaredFields();
StringBuilder baseDoSql = new StringBuilder();
for (Field field : fields) {
// 表字段
String columnName = StrUtil.toUnderlineCase(field.getName()); // name修改为表字段格式
// 数据类型
String columnType = fieldTypeConvDataTypeUtil(field.getType());
baseDoSql.append(" " + columnName + " " + columnType + " COMMENT '" + field.getName() + "',\n");
}
return baseDoSql;
}
/**
* 根据字段类型设置SQL中的数据类型
*
* @param fileType 字段类型
* @return columnType 数据类型
*/
static String fieldTypeConvDataTypeUtil(Class<?> fileType) {
String columnType = null;
// 根据字段类型设置SQL中的数据类型
if (fileType == Long.class || fileType == long.class) {
columnType = "BIGINT";
} else if (fileType == Integer.class || fileType == int.class) {
columnType = "INT";
} else if (fileType == Short.class || fileType == short.class) {
columnType = "SMALLINT";
} else if (fileType == Byte.class || fileType == byte.class) {
columnType = "TINYINT";
} else if (fileType == Float.class || fileType == float.class) {
columnType = "FLOAT";
} else if (fileType == Double.class || fileType == double.class) {
columnType = "DOUBLE";
} else if (fileType == Boolean.class || fileType == boolean.class) {
columnType = "TINYINT(1)"; // 布尔类型通常可以映射为TINYINT(1)
} else if (fileType == String.class) {
// 假设字符串字段最大长度为255
columnType = "VARCHAR(255)";
} else if (fileType == java.util.Date.class || fileType == java.sql.Date.class
|| fileType == java.sql.Timestamp.class || fileType == java.time.LocalDate.class
|| fileType == java.time.LocalDateTime.class) {
// 日期和时间类型
columnType = "DATETIME"; // 或者你可以选择TIMESTAMP, DATE等
} else if (fileType == BigDecimal.class) {
// 假设BigDecimal的精度为19,小数位为2
columnType = "DECIMAL(19, 2)";
} else if (fileType.isArray()) {
// 数组类型在SQL中通常不直接支持,可能需要序列化或转换为其他类型
throw new IllegalStateException("Unsupported field type: array");
} else if (fileType.isEnum()) {
// 枚举类型通常映射为VARCHAR或INT,取决于存储方式
columnType = "VARCHAR(255)"; // 假设使用VARCHAR存储枚举的字符串表示
} else {
// 其他类型可能需要特殊处理或自定义映射
// throw new IllegalStateException("不支持的字段类型: " + fileType);
columnType = "VARCHAR(255)";
}
return columnType;
}
}
根据实体类生成mysql表CREATE语句
于 2024-06-25 13:54:56 首次发布