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