首页 > 数据库 >根据java已经定义好的Class生成DDL SQL

根据java已经定义好的Class生成DDL SQL

时间:2024-03-04 10:23:10浏览次数:26  
标签:java String javaFiled2TableColumnMappingMap SQL DDL put import null annotation

package com.ai.exchange.generator;

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.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.util.*;

/** * @Title SqlGenerator * 
@Description 根据JAVA实体生成SQL建表语句工具

*/ @Slf4j public class JavaObject2SqlDDLGenerator { /** * 常见MYSQL字段类型 VS java对象属性类型 映射集合 */ public static Map<String, String> javaFiled2TableColumnMappingMap = new HashMap<>(); static { javaFiled2TableColumnMappingMap.put("integer", "int(10)"); javaFiled2TableColumnMappingMap.put("short", "tinyint"); javaFiled2TableColumnMappingMap.put("long", "bigint"); javaFiled2TableColumnMappingMap.put("bigDecimal", "decimal(19,2)"); javaFiled2TableColumnMappingMap.put("double", "double(10,2)"); javaFiled2TableColumnMappingMap.put("float", "float"); javaFiled2TableColumnMappingMap.put("boolean", "bit"); javaFiled2TableColumnMappingMap.put("timeStamp", "datetime"); javaFiled2TableColumnMappingMap.put("date", "datetime"); javaFiled2TableColumnMappingMap.put("string", "varchar(200)"); javaFiled2TableColumnMappingMap.put("localDateTime", "datetime"); } /** * 生成SQL * @param className * @param tableName * @param primaryKey * @param filePath * @return */ public static String ddlSqlGenerate(String className,String tableName,String primaryKey,String filePath){ try { Class<?> clz = Class.forName(className); Field[] fields = clz.getDeclaredFields(); // 获取该类的父类下的字段 Class<?> superclass = clz.getSuperclass(); Field[] declaredFields = superclass.getDeclaredFields(); List<Field> fieldList = new ArrayList<>(); for (Field declaredField : declaredFields) { fieldList.add(declaredField); } for (Field declaredField : fields) { fieldList.add(declaredField); } // 查询主键字段 String sqlPrimaryKey = null; Field keyField = null; StringBuffer column = new StringBuffer(); for (int i = 0; i < fieldList.size(); i++) { Field f = fieldList.get(i); if (StringUtils.isNotBlank(primaryKey) && f.getName().equals(primaryKey)){ // 根据TableId 注释获取逐渐信息 TableId annotation = f.getAnnotation(TableId.class); if(null != annotation){ IdType type = annotation.type(); if(IdType.AUTO == type){ sqlPrimaryKey = " \n `"+primaryKey+"` int(16) not null auto_increment primary key,"; }else{ sqlPrimaryKey = " \n `"+primaryKey+"` varchar(100),"; } }else{ sqlPrimaryKey = " \n `"+primaryKey+"` varchar(100) ,"; } continue; } // 剔除序列化自动生成的字段 if(f.getName().equalsIgnoreCase("serialVersionUID")){ continue; } TableId tableId = f.getAnnotation(TableId.class); if(null != tableId){ keyField = f; continue; } // 跳过不是表字段的属性@TableField(exist=false) TableField annotation = f.getAnnotation(TableField.class); if(null != annotation){ boolean exist = annotation.exist(); if(!exist){ continue; } } // 最后一行SQL字符串特殊处理 if(i == fieldList.size() - 1){ column.append(wrapperTableColumnSql(f,false)); }else{ column.append(wrapperTableColumnSql(f,true)); } } // 如果没参数中指定主键,则根据注释@TableId自动捕获 if(StringUtils.isBlank(primaryKey)){ if(null != keyField){ TableId tableId = keyField.getAnnotation(TableId.class); IdType type = tableId.type(); String columnName = StringUtils.camelToUnderline(keyField.getName()).toLowerCase(); if(IdType.AUTO == type){ sqlPrimaryKey = " \n `"+columnName+"` int(16) not null auto_increment primary key,"; }else{ sqlPrimaryKey = " \n `"+columnName+"` varchar(100),"; } } } // 从注解@ApiModel获取表名称(description、value) ApiModel annotation = clz.getAnnotation(ApiModel.class); String tableNameCn = null; if(null != annotation){ tableNameCn = annotation.description(); if(StringUtils.isNotBlank(tableNameCn)){ if(!tableNameCn.endsWith("表")){ tableNameCn += "表"; } }else{ tableNameCn = annotation.value(); if(!tableNameCn.endsWith("表")){ tableNameCn += "表"; } } } // 从注解@TableName获取表名称 if(StringUtils.isBlank(tableName)){ TableName tName = clz.getAnnotation(TableName.class); String value = tName.value(); tableName = value; } StringBuffer sql = new StringBuffer(); sql.append("\n drop table if exists `"+tableName+"`; ") .append(" \n create table `"+tableName+"` (") .append(StringUtils.isNotBlank(sqlPrimaryKey) ? sqlPrimaryKey : "") .append(" \n "+column) .append(" ) engine = innodb character set = utf8 collate = utf8_general_ci") .append(StringUtils.isNotBlank(tableName) ? " comment='"+tableNameCn+"'" : "") .append(";"); String sqlText = sql.toString(); if(StringUtils.isNotBlank(filePath)){ sqlSave2File(sqlText,filePath); } return sqlText; } catch (ClassNotFoundException e) { log.debug("SQL生成异常:",e); return null; } } /** * 构建字段部分 * @param field * @return */ private static String wrapperTableColumnSql(Field field,boolean containQuota){ String tpl = containQuota ? "`%s` %s default null comment '%s', \n" : "`%s` %s default null comment '%s' \n"; String typeName = field.getType().getSimpleName().toLowerCase(); String sqlType = javaFiled2TableColumnMappingMap.get(typeName); if (sqlType == null || sqlType.isEmpty()){ log.info(field.getName() + ":"+field.getType().getName()+" 需要单独创建表"); return ""; } String comment = ""; // 从注解@ApiModelProperty获取字段信息 ApiModelProperty annotation = field.getAnnotation(ApiModelProperty.class); if(null != annotation){ comment = annotation.value(); if("".equalsIgnoreCase(comment)){ comment = annotation.name(); } if("".equalsIgnoreCase(comment)){ comment = annotation.notes(); } } // 将java对象属性值的驼峰写法转换为下划线模式 String column = StringUtils.camelToUnderline(field.getName()).toLowerCase(); String sql = String.format(tpl,column,sqlType.toLowerCase(),comment); return sql; } /** * 生成的SQL保存指定文件 * @param str * @param path */ private static void sqlSave2File(String str,String path){ byte[] sourceByte = str.getBytes(); if(null != sourceByte){ try { File file = new File(path); if (!file.exists()) { File dir = new File(file.getParent()); dir.mkdirs(); file.createNewFile(); } FileOutputStream outStream = new FileOutputStream(file); outStream.write(sourceByte); outStream.flush(); outStream.close(); System.out.println("生成成功"); } catch (Exception e) { log.debug("保存SQL文件异常:",e); } } } public static void main(String[] args) { String str = ddlSqlGenerate("com.ai.exchange.entity.ExApiZabbixCloudHostMonitorItem", "ex_api_zabbix_cloud_host_monitor_item", null, null); log.error(str); } }

  

标签:java,String,javaFiled2TableColumnMappingMap,SQL,DDL,put,import,null,annotation
From: https://www.cnblogs.com/dduo/p/18051278

相关文章

  • MySQL 查找并删除重复行
    本文讲述如何查找数据库里重复的行。这是初学者十分普遍遇到的问题。方法也很简单。这个问题还可以有其他演变,例如,如何查找“两字段重复的行”(#mysqlIRC频道问到的问题)如何查找重复行第一步是定义什么样的行才是重复行。多数情况下很简单:它们某一列具有相同的值。本文采用这一......
  • 「Java开发指南」MyEclipse如何支持Spring Scaffolding?(四)
    在上文中主要为大家介绍了应用程序分层、代码助手等内容,本文将继续介绍SpringDSL模型等。MyEclipsev2023.1.2离线版下载MyEclipse技术交流群:742336981欢迎一起进群讨论5.SpringDSL模型支持Spring的MyEclipse还有一个特性,它是面向那些希望通过使用抽象层(模型驱动开发)来......
  • RDS for MySQL Serverless公测上线:弹性伸缩,最高可降成本超80%
    本文分享自华为云社区《RDSforMySQLServerless公测上线:弹性伸缩,最高可降成本超80%》,作者:GaussDB数据库。随着科技的快速发展,我们正在迅速步入一个全新的数字化时代。数字化时代,数据是最宝贵的资源。数据库作为存储数据的仓库,重要性更是不言而喻。一、业务背景及痛点为了确......
  • mysql安装
    一、环境配置检测系统是否自带Mysql#rmp-qa|grepmysql如果有进行强行卸载#rpm-e--nodepsmysql-libs-5.1.52-1.el6_0.1.x86_64检测系统是否自带mariadb#rpm-qa|grepmariadb#rpm-e--nodepsmariadb-libs-5.5.64-1.el7.x86_64#rpm-e--nodepsmariadb-5.5.64-1.el7......
  • 没想到,JDBC 驱动会偷偷修改 sql_mode 的会话值
    最近碰到一个case,值得分享一下。现象就是一个update操作,在mysql客户端中执行提示warning,但在java程序中执行却又报错。问题重现mysql> create table test.t1(id int primary key, c1 datetime);Query OK, 0 rows affected (0.01 sec)mysql> insert int......
  • 数据库SQL行专列和列转行
    行转列适用于按照数据的某个维度的聚合,例如成绩单,按照学生姓名整合各科成绩;列转行适用于拆分某条数据的各属性,例如拆分学生成绩单,按名称、学科、成绩展示;行转列方法:通常使用聚合函数对数据进行处理,例如sum、max、count等SELECTuser_name,MAX(CASEcourseWHEN'数学'T......
  • Java编程的利器:Pair和Triple无缝解决多值返回问题,助力编写高效代码
    在实际编码中,经常会遇到一个方法需要返回多个值的情况,你编写一个方法,需要同时返回某个操作的结果和一些相关的附加信息。使用传统的方式,你可能需要创建一个包含这些信息的自定义类或者使用集合(如Map)来存储这些值。然而,这往往使得代码变得臃肿,而且对于调用方来说,理解和提取这些值......
  • Java 21 终于对这些功能动刀了!!
    来源:https://medium.com/@benweidig尽管Java是我使用过的向后兼容程度最高的语言和环境之一,但始终存在功能弃用甚至删除的可能性。Java21将弃用两个功能,这就是我们今天要讨论的内容。推荐一个开源免费的SpringBoot实战项目:https://github.com/javastacks/spring-boot-b......
  • MySQL查看执行慢的SQL语句(慢查询)
    更新日志点击查看2024年3月4日发布。慢查询日志查看执行慢的SQL语句,需要先开启慢查询日志。MySQL的慢查询日志,记录在MySQL中响应时间超过阀值的语句(具体指运行时间超过long_query_time值的SQL。long_query_time的默认值为10,意思是运行10秒以上(不含10秒)的语句)。......
  • sql常见四种连接查询
    原文链接:https://learn.microsoft.com/zh-CN/sql/relational-databases/performance/joins?view=aps-pdw-2016-au7         https://www.cnblogs.com/alone-striver/p/9055078.html1、内部联接  INNERJOIN2、左外部联接  LEFT[OUTER]JOIN3、右......