• Springboot 3.0.0基于swagger3.0的根据实体类建表SQL语句(postgresql系类数据库)


    package com.xxx.xxxx.utils;
    
    import java.lang.reflect.Field;
    import java.math.BigDecimal;
    import java.time.LocalDateTime;
    import java.util.HashMap;
    import java.util.Map;
    
    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import com.cqcloud.platform.entity.SysPaymentInfo;
    
    import cn.hutool.core.lang.Console;
    import io.swagger.v3.oas.annotations.media.Schema;
    
    /**
     * 根据实体创建表sql语句
     * @author weimeilayer@gmail.com ✨
     * @date 💓💕 2024年8月6日 🐬🐇 💓💕
     */
    public class SqlGenerator {
    
        public static String createTableSql(Class<?> clazz) {
            // 检查类是否包含 @TableName 注解
            if (!clazz.isAnnotationPresent(TableName.class)) {
                throw new IllegalArgumentException("The class must be annotated with @TableName");
            }
    
            // 初始化 StringBuilder 来构建 SQL 语句
            StringBuilder sql = new StringBuilder();
            TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
            String tableName = tableNameAnnotation.value();
    
            // 获取类级别的 @Schema 注解
            Schema classSchema = clazz.getAnnotation(Schema.class);
            String tableComment = (classSchema != null) ? classSchema.description() : clazz.getSimpleName();
    
            // 构建 SQL 语句的初始部分
            sql.append("drop table if exists ").append(tableName).append(" cascade;\n");
            sql.append("create table ").append(tableName).append(" (\n");
    
            // 获取类的所有字段
            Field[] fields = clazz.getDeclaredFields();
            String primaryKey = null;
            Map<String, String> columnComments = new HashMap<>();
    
            // 遍历每个字段
            for (Field field : fields) {
                // 跳过 serialVersionUID 字段
                if (field.getName().equals("serialVersionUID")) {
                    continue;
                }
    
                // 跳过被 @TableField 注解并且 exist 属性为 false 的字段
                if (field.isAnnotationPresent(TableField.class) && field.getAnnotation(TableField.class).exist() == false) {
                    continue;
                }
    
                // 初始化列名和列类型
                String columnName;
                String columnType = null;
    
                // 检查字段是否被 @TableId 注解
                if (field.isAnnotationPresent(TableId.class)) {
                    TableId tableId = field.getAnnotation(TableId.class);
                    columnName = tableId.value();
                    if (tableId.type() == IdType.ASSIGN_ID) {
                        primaryKey = columnName;
                    }
                } else {
                    TableField tableField = field.getAnnotation(TableField.class);
                    columnName = (tableField != null && !tableField.value().isEmpty()) ? tableField.value() : field.getName();
                }
    
                // 将列名从驼峰命名转换为下划线命名
                columnName = convertToUnderscore(columnName);
    
                // 根据字段类型设置列类型
                Class<?> fieldType = field.getType();
                if (fieldType == String.class) {
                    columnType = "varchar(255)";
                } else if (fieldType == int.class || fieldType == Integer.class) {
                    columnType = "integer";
                } else if (fieldType == long.class || fieldType == Long.class) {
                    columnType = "bigint";
                } else if (fieldType == double.class || fieldType == Double.class) {
                    columnType = "double precision";
                } else if (fieldType == BigDecimal.class) {
                    columnType = "numeric(19, 2)";
                } else if (fieldType == boolean.class || fieldType == Boolean.class) {
                    columnType = "boolean";
                } else if (fieldType == LocalDateTime.class) {
                    columnType = "timestamp";
                }
    
                // 处理 @Schema 注解以获取列注释
                if (field.isAnnotationPresent(Schema.class)) {
                    Schema schema = field.getAnnotation(Schema.class);
                    columnComments.put(columnName, schema.description());
                }
    
                // 构建列定义部分的 SQL 语句
                sql.append("    ").append(columnName).append(" ").append(columnType);
    
                // 如果字段被 @TableId 注解,设置为主键
                if (field.isAnnotationPresent(TableId.class)) {
                    sql.append(" primary key");
                }
    
                // 处理 @TableField 注解以设置默认值
                if (field.isAnnotationPresent(TableField.class)) {
                    TableField tableField = field.getAnnotation(TableField.class);
                    if (tableField.fill() == FieldFill.INSERT || tableField.fill() == FieldFill.UPDATE) {
                        sql.append(" default current_timestamp");
                    }
                }
    
                // 添加列定义的结尾部分
                sql.append(",\n");
            }
    
            // 删除最后一个逗号并完成 SQL 语句
            sql.setLength(sql.length() - 2); // Remove the last comma
            sql.append("\n);\n");
    
            // 添加表和列的注释
            sql.append("comment on table \"public\".\"").append(tableName).append("\" IS '").append(tableComment).append("';\n");
    
            if (!columnComments.isEmpty()) {
                columnComments.forEach((columnName, comment) -> {
                    sql.append("comment on column ").append(tableName).append(".").append(columnName)
                            .append(" IS '").append(comment).append("';\n");
                });
            }
    
            // 打印 SQL 语句
            Console.log(sql);
            return sql.toString();
        }
    
        // 辅助方法:将驼峰命名转换为下划线命名
        private static String convertToUnderscore(String camelCase) {
            StringBuilder result = new StringBuilder();
            for (char c : camelCase.toCharArray()) {
                if (Character.isUpperCase(c)) {
                    result.append('_').append(Character.toLowerCase(c));
                } else {
                    result.append(c);
                }
            }
            return result.toString();
        }
    
        // 执行调用方法
        public static void main(String[] args) {
            createTableSql(SysPaymentInfo.class);
        }
    }
    
    

    运行结果
    在这里插入图片描述
    实体案例
    在这里插入图片描述

  • 相关阅读:
    字符串的转换路径问题
    offline 2 online | 重要性采样,把 offline + online 数据化为 on-policy samples
    ChatGPT API接口编程基础与使用技巧
    云原生中间件RocketMQ-消费者核心参数、消费模式之集群模式
    opencv编译错误记录
    计算机毕业设计django基于python药房药品管理系统(源码+系统+mysql数据库+Lw文档)
    【Qt之JSON文件】QJsonDocument、QJsonObject、QJsonArray等类介绍及使用
    C/C++数据结构课程设计安排
    花千骨歌曲大全 附简谱
    Go runtime 调度器精讲(八):运行时间过长的抢占
  • 原文地址:https://blog.csdn.net/weimeilayer/article/details/140959001