背景说明
因业务要求,需要将实体类转为MYSQL建表语句
在工作中,出于数据对接的需求,对方提供了一份接口文档,字段都是非标准驼峰格式的。
我们接收对方数据后落库保存,需要将每个驼峰字段转化保存到数据库表中,因为字段太多,一个个复制太痛苦。虽说SpringJPA也有功能,可以将实体类生成表结构,但是还需要搭一套SpringJPA工程,还是觉得麻烦。
权衡之下写了个实体类工具,不依赖任何框架,有Java8的环境就能运行
也没什么严谨性,就是临时用的。
这里记录一下,怕以后找不到了。
开始
1.建了个注解, 方便备注数据库字段
import java.lang.annotation.*;
/**
1. JAVA生成SQL的字段备注
*/
@Documented
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ziduan {
String notes() default "";
}
2. 准备UserEntity
因为我是word文档接收的,字段名+注释,用Sublime或者其他文本编辑器,采用列编辑的方式,已经处理对应的字段名和字段类型,并生成类信息了,具体文本编辑过程不再赘述。
@Data
public class UserEntity {
@Ziduan(notes = "id")
private Integer Id;
@Ziduan(notes = "用户ID")
private Integer UserId;
@Ziduan(notes = "用户名")
private String UserName;
@Ziduan(notes = "余额")
private BigDecimal amount;
@Ziduan(notes = "编号")
private String SeriNo;
@Ziduan(notes = "创建时间")
private LocalDateTime CreateTime;
@Ziduan(notes = "更新时间")
private LocalDateTime UpdateTime;
}
- 运行工具类
启动 main 方法,传入类作为参数就可以运行了
import java.lang.reflect.Field;
import java.util.regex.Pattern;
public class EntityToSQLGenerator {
private static Pattern humpPattern = Pattern.compile("[A-Z]");
public static void main(String[] args) {
/**
* 按实体类生成建表语句
*/
System.out.println(generateCreateTableSQL(UserEntity.class));
/**
* 测试驼峰转字段,如: UserInfoEntity -> user_info_entity
*/
//System.out.println(parseField("UserInfoEntity"));
}
public static String generateCreateTableSQL(Class<?> clazz) {
StringBuilder sql = new StringBuilder("CREATE TABLE ");
sql.append(parseField(clazz.getSimpleName())).append(" (");
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Ziduan tf = field.getAnnotation(Ziduan.class);
//获取字段备注
StringBuilder sep = new StringBuilder("'").append(tf.notes()).append("'");
String fieldName = parseField(field.getName());
String fieldType = field.getType().getSimpleName();
sql.append(fieldName).append(" ");
// 具体字段长度或者精确度,需要自己按情况调整
switch (fieldType) {
case "Long":
sql.append("BIGINT COMMENT ").append(sep);
break;
case "String":
sql.append("VARCHAR(100) DEFAULT '' COMMENT ").append(sep);
break;
case "Integer":
sql.append("INT(10) COMMENT ").append(sep);
break;
case "BigDecimal":
sql.append("DECIMAL(20,4) COMMENT ").append(sep);
break;
case "LocalDateTime":
sql.append("DATETIME COMMENT ").append(sep);
//....可以增加更多数据类型的处理
}
if (i < fields.length - 1) {
sql.append(", ");
}
}
sql.append(");");
return sql.toString();
}
private static String parseField(String name) {
char[] chars = name.toCharArray();
StringBuilder b = new StringBuilder();
boolean preIsXiaoxie = false;
for (int i = 0; i < chars.length; i++) {
char aChar = chars[i];
if (humpPattern.matcher(String.valueOf(aChar)).find()) {
if (preIsXiaoxie) {
if (i != 0) {
b.append("_");
}
}
preIsXiaoxie = false;
if (i == chars.length - 1) {
b.append(String.valueOf(aChar).toLowerCase());
} else {
b.append(String.valueOf(aChar).toLowerCase());
}
} else {
preIsXiaoxie = true;
b.append(aChar);
}
}
return b.toString();
}
}
4. 生成SQL如下
需要调整字段长度、默认值、主键、索引,在这个基础上操作就行。
附上SQL在线解析地址:https://www.jyshare.com/front-end/701/
CREATE TABLE user_entity (
id BIGINT COMMENT 'id',
user_id INT(10) COMMENT '用户ID',
user_name VARCHAR(100) COMMENT '用户名',
amount DECIMAL(20, 4) COMMENT '余额',
seri_no VARCHAR(100) COMMENT '编号',
create_time DATETIME COMMENT '创建时间',
update_time DATETIME COMMENT '更新时间'
);