根据实体类生成mysql表CREATE语句

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;
    }
}

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Java 中,可以使用第三方库或框架来实现实体类MySQL create table 语句。常用的第三方库有 Mybatis Generator 和 JPA-Auto。这些库可以根据实体类的注解和属性,自动生成对应的 MySQL create table 语句。 示例: 1.使用Mybatis Generator ```xml <generatorConfiguration> <context id="DB2Tables" targetRuntime="MyBatis3"> <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC" userId="root" password="root"> </jdbcConnection> <javaModelGenerator targetPackage="com.mybatis.model" targetProject="src/main/java"> </javaModelGenerator> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"> </sqlMapGenerator> <javaClientGenerator type="XMLMAPPER" targetPackage="com.mybatis.dao" targetProject="src/main/java"> </javaClientGenerator> <table tableName="test_table" domainObjectName="TestTable"> <generatedKey column="id" sqlStatement="JDBC" identity="true"/> </table> </context> </generatorConfiguration> ``` 2.使用 JPA-Auto ```java @Entity @Table(name = "employee") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name", nullable = false) private String name; @Column(name = "age", nullable = false) private Integer age; // getters and setters } ``` 使用jpa-auto 生成对应的 create table 语句 ``` mvn jpa-auto:generate ``` 注意: - 使用第三方库或框架时需要先安装相应的包。 - 上述两个示例只是简单的用法,实际使用时还需要根据需求进行配置。 希望这能帮到你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值