|
|
@@ -0,0 +1,779 @@
|
|
|
+package jp.yamoto.farm.common.dev;
|
|
|
+
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
+
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileWriter;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+public class ExcelToJavaGenerator {
|
|
|
+ public static void main(String[] args) {
|
|
|
+ // 文件路径配置
|
|
|
+ String excelFilePath = "/Users/apple/mywork-gs/svn/ds-yamoto-farm/20_設計/02_DB設計書/テーブル設計書_ヤマト運輸様|農家(農業法人)支援システム_v1.0.xlsx"; // 输入的Excel文件路径
|
|
|
+ String outputSqlPath = "/Users/apple/mywork-gs/svn/ds-yamoto-farm/20_設計/02_DB設計書/codes"; // 输出的SQL文件路径
|
|
|
+ generateMapperL(excelFilePath,outputSqlPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void generateMapperL(String excelFilePath,String outputSqlPath) {
|
|
|
+
|
|
|
+ List<String> fieldGenerateLst = new ArrayList<String>();
|
|
|
+ fieldGenerateLst.add(excelFilePath);
|
|
|
+ fieldGenerateLst.add("create_time");
|
|
|
+ fieldGenerateLst.add("create_by");
|
|
|
+ fieldGenerateLst.add("create_pg_id");
|
|
|
+ fieldGenerateLst.add("update_time");
|
|
|
+ fieldGenerateLst.add("update_by");
|
|
|
+ fieldGenerateLst.add("update_pg_id");
|
|
|
+ fieldGenerateLst.add("version");
|
|
|
+
|
|
|
+ try (FileInputStream fis = new FileInputStream(excelFilePath);
|
|
|
+ Workbook workbook = getWorkbook(fis, excelFilePath)) {
|
|
|
+
|
|
|
+ // 创建输出目录(如果不存在)
|
|
|
+ Path outputDir = Paths.get(outputSqlPath);
|
|
|
+ if (!Files.exists(outputDir)) {
|
|
|
+ Files.createDirectories(outputDir);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 遍历每个Sheet,每个Sheet生成一个文件
|
|
|
+ for (int sheetIndex = 2; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
|
|
|
+// if (sheetIndex > 6) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+
|
|
|
+ Sheet sheet = workbook.getSheetAt(sheetIndex);
|
|
|
+ Row rowTable = sheet.getRow(1);
|
|
|
+
|
|
|
+ if (rowTable == null || rowTable.getCell(27) == null) {
|
|
|
+ System.out.println("Sheet " + sheetIndex + " 没有找到表名信息,跳过");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 表名
|
|
|
+ String tableName = rowTable.getCell(27).getStringCellValue();
|
|
|
+ String tablrNameHanzi = sheet.getRow(0).getCell(27).getStringCellValue();
|
|
|
+ // 驼峰表名
|
|
|
+ String camelTableName = convertToCamelCase(tableName);
|
|
|
+ // 首字母大些驼峰表名
|
|
|
+ String camelTableName2 = convertToPascalCase(tableName);
|
|
|
+
|
|
|
+ Map<String,StringBuilder> generateBuilder = generateCodes(sheet, tableName,
|
|
|
+ camelTableName, camelTableName2, tablrNameHanzi , fieldGenerateLst);
|
|
|
+
|
|
|
+ for(String key : generateBuilder.keySet()) {
|
|
|
+
|
|
|
+ StringBuilder outTempPathBuilder = new StringBuilder();
|
|
|
+ outTempPathBuilder.append(outputSqlPath + "/" + key);
|
|
|
+ // 创建输出目录(如果不存在)
|
|
|
+ String fileOutTempPath = outTempPathBuilder.toString();
|
|
|
+ outputDir = Paths.get(fileOutTempPath);
|
|
|
+ if (!Files.exists(outputDir)) {
|
|
|
+ Files.createDirectories(outputDir);
|
|
|
+ }
|
|
|
+
|
|
|
+ outTempPathBuilder.append( "/" + camelTableName2);
|
|
|
+ if("mapper".equals(key)) {
|
|
|
+ outTempPathBuilder.append( "Mapper.xml" );
|
|
|
+ }else if("entity".equals(key)) {
|
|
|
+ outTempPathBuilder.append(".java" );
|
|
|
+ } else if("inteface".equals(key)) {
|
|
|
+ outTempPathBuilder.append("Mapper.java" );
|
|
|
+ } else if("json".equals(key)) {
|
|
|
+ outTempPathBuilder.append("Json.txt" );
|
|
|
+ } else if("message".equals(key)) {
|
|
|
+ outTempPathBuilder.append("Message.txt" );
|
|
|
+ }else if("entityVo".equals(key)) {
|
|
|
+ outTempPathBuilder.append("Vo").append(".java" );
|
|
|
+ } else if("entityBo".equals(key)) {
|
|
|
+ outTempPathBuilder.append("Bo").append(".java" );
|
|
|
+ }
|
|
|
+ // 为每个Sheet创建独立的文件
|
|
|
+ Path filePath = Paths.get(outTempPathBuilder.toString());
|
|
|
+
|
|
|
+ // 删除已存在的文件[6,7](@ref)
|
|
|
+ if (Files.exists(filePath)) {
|
|
|
+ try {
|
|
|
+ Files.deleteIfExists(filePath);
|
|
|
+ System.out.println("文件已删除: " + filePath);
|
|
|
+ } catch (IOException e) {
|
|
|
+ System.err.println("删除文件时发生错误: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 为当前Sheet构建Mapper内容
|
|
|
+ StringBuilder sheetMapperContent = generateBuilder.get(key);
|
|
|
+
|
|
|
+ // 为每个Sheet单独写入文件[6,8](@ref)
|
|
|
+ try (FileWriter writer = new FileWriter(filePath.toFile())) {
|
|
|
+ writer.write(sheetMapperContent.toString());
|
|
|
+ System.out.println("Mapper已生成: " + filePath);
|
|
|
+ } catch (IOException e) {
|
|
|
+ System.err.println("写入文件时发生错误: " + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为单个Sheet构建Mapper内容
|
|
|
+ */
|
|
|
+ private static Map<String,StringBuilder> generateCodes(Sheet sheet, String tableName,String camelTableName, String camelTableName2, String tablrNameHanzi, List<String> fieldGenerateLst) {
|
|
|
+
|
|
|
+
|
|
|
+ Map<String,StringBuilder> generateBuilder =new HashMap<String,StringBuilder>();
|
|
|
+
|
|
|
+ // Mapper
|
|
|
+ StringBuilder mapperContent = new StringBuilder();
|
|
|
+ // Result列Builder
|
|
|
+ StringBuilder resultMapColumnSb = new StringBuilder();
|
|
|
+ // Select field Builder
|
|
|
+ StringBuilder selectFieldMapColumnSb = new StringBuilder();
|
|
|
+ // Select List Builder
|
|
|
+ StringBuilder selectListMapColumnSb = new StringBuilder();
|
|
|
+ // Select By Id Builder
|
|
|
+ StringBuilder selectByIdMapColumnSb = new StringBuilder();
|
|
|
+ // Insert Builder
|
|
|
+ StringBuilder insertBeforeMapColumnSb = new StringBuilder();
|
|
|
+ StringBuilder insertAfterMapColumnSb = new StringBuilder();
|
|
|
+ // Update Builder
|
|
|
+ StringBuilder updateMapColumnSb = new StringBuilder();
|
|
|
+
|
|
|
+ // Entity
|
|
|
+ StringBuilder entityContent = new StringBuilder();
|
|
|
+ StringBuilder entityFieldMapSb = new StringBuilder();
|
|
|
+ StringBuilder entityContentVo = new StringBuilder();
|
|
|
+ StringBuilder entityContentBo = new StringBuilder();
|
|
|
+ StringBuilder entityFieldMapSbBo = new StringBuilder();
|
|
|
+ // Json
|
|
|
+ StringBuilder jsonFieldMapSb = new StringBuilder();
|
|
|
+
|
|
|
+ // Message
|
|
|
+ StringBuilder jsonMessageMapSb = new StringBuilder();
|
|
|
+
|
|
|
+ // Inteface
|
|
|
+ StringBuilder intefaceContent = new StringBuilder();
|
|
|
+
|
|
|
+ boolean hasPrimaryKey = false;
|
|
|
+ String primaryKeyColumn = null;
|
|
|
+
|
|
|
+ int startRow = 8; // 通常第1行 (索引0) 是标题行,数据从第2行开始
|
|
|
+ for (int rowIndex = startRow; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
|
|
|
+ Row row = sheet.getRow(rowIndex);
|
|
|
+ if (row == null || isEmptyRow(row)) continue;
|
|
|
+
|
|
|
+ // 解析单元格,假设列顺序为:字段名, 类型, 长度, 是否主键, 是否允许空, 默认值, 注释
|
|
|
+ String fieldName = getCellValueSafe(row.getCell(12));
|
|
|
+ if(fieldName == null || fieldName =="") {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ String camelFieldName = convertToCamelCase(fieldName);
|
|
|
+
|
|
|
+ String fieldType = getCellValueSafe(row.getCell(21));
|
|
|
+ String fieldLength = getCellValueSafe(row.getCell(24));
|
|
|
+ String fieldDit = getCellValueSafe(row.getCell(26));
|
|
|
+ String isPrimaryKey = getCellValueSafe(row.getCell(33));
|
|
|
+ String searchField = "";
|
|
|
+ String isSeachCode = getCellValueSafe(row.getCell(34));
|
|
|
+ String isNullable = getCellValueSafe(row.getCell(28));
|
|
|
+ String defaultValue = getCellValueSafe(row.getCell(30));
|
|
|
+ String fieldComment = getCellValueSafe(row.getCell(2));
|
|
|
+
|
|
|
+ if (fieldName == null || fieldName.trim().isEmpty()) {
|
|
|
+ break; // 遇到空行则结束当前表的解析
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!fieldGenerateLst.contains(fieldName)) {
|
|
|
+ // 开始拼接单个字段定义
|
|
|
+ entityFieldMapSb.append(" /**").append("\n");
|
|
|
+ entityFieldMapSb.append(" * ").append(fieldComment) .append("\n");
|
|
|
+ entityFieldMapSb.append(" */").append("\n");
|
|
|
+ entityFieldMapSb.append(" private ");
|
|
|
+
|
|
|
+ // 处理数据类型和长度
|
|
|
+ if (("varchar".equalsIgnoreCase(fieldType)
|
|
|
+ || ("text".equalsIgnoreCase(fieldType)) && !fieldLength.isEmpty()) ) {
|
|
|
+ entityFieldMapSb.append("String");
|
|
|
+
|
|
|
+ } else if ("DECIMAL".equalsIgnoreCase(fieldType) && !fieldLength.isEmpty()) {
|
|
|
+ entityFieldMapSb.append("BigDecimal");
|
|
|
+ } else if ("timestamp".equalsIgnoreCase(fieldType) && !fieldLength.isEmpty()) {
|
|
|
+ entityFieldMapSb.append("Date");
|
|
|
+ } else if ("integer".equalsIgnoreCase(fieldType) && !fieldLength.isEmpty()) {
|
|
|
+ entityFieldMapSb.append("Integer");
|
|
|
+ } else {
|
|
|
+ entityFieldMapSb.append("String");
|
|
|
+ }
|
|
|
+ entityFieldMapSb.append(" ");
|
|
|
+ entityFieldMapSb.append(camelFieldName).append(";") .append("\n");
|
|
|
+ entityFieldMapSb.append("\n");
|
|
|
+
|
|
|
+ // 开始拼接单个字段定义
|
|
|
+ entityFieldMapSbBo.append(" /**").append("\n");
|
|
|
+ entityFieldMapSbBo.append(" * ").append(fieldComment) .append("\n");
|
|
|
+ entityFieldMapSbBo.append(" */").append("\n");
|
|
|
+
|
|
|
+ if(isNullable.equals("NO") && "varchar".equalsIgnoreCase(fieldType) ) {
|
|
|
+ entityFieldMapSbBo.append(" @LmNotBlank(params = {\"{").append(camelFieldName).append("}\"}, groups = {ValidatorGroup.AddGroup.class, ValidatorGroup.UpdateGroup.class})") .append("\n");;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ("varchar".equalsIgnoreCase(fieldType) ) {
|
|
|
+ entityFieldMapSbBo.append(" @LmLength(min = 1, max = ").append(fieldLength).append(", params = {\"{")
|
|
|
+ .append(camelFieldName).append("}\", \"").append(fieldLength).append("\"}, groups = {ValidatorGroup.AddGroup.class, ValidatorGroup.UpdateGroup.class})") .append("\n");;
|
|
|
+ }
|
|
|
+
|
|
|
+ entityFieldMapSbBo.append(" private ");
|
|
|
+ // 处理数据类型和长度
|
|
|
+ if (("varchar".equalsIgnoreCase(fieldType)
|
|
|
+ || ("text".equalsIgnoreCase(fieldType)) && !fieldLength.isEmpty()) ) {
|
|
|
+ entityFieldMapSbBo.append("String");
|
|
|
+
|
|
|
+ } else if ("DECIMAL".equalsIgnoreCase(fieldType) && !fieldLength.isEmpty()) {
|
|
|
+ entityFieldMapSbBo.append("BigDecimal");
|
|
|
+ } else if ("timestamp".equalsIgnoreCase(fieldType) && !fieldLength.isEmpty()) {
|
|
|
+ entityFieldMapSbBo.append("Date");
|
|
|
+ } else if ("integer".equalsIgnoreCase(fieldType) && !fieldLength.isEmpty()) {
|
|
|
+ entityFieldMapSbBo.append("Integer");
|
|
|
+ } else {
|
|
|
+ entityFieldMapSbBo.append("String");
|
|
|
+ }
|
|
|
+ entityFieldMapSbBo.append(" ");
|
|
|
+ entityFieldMapSbBo.append(camelFieldName).append(";") .append("\n");
|
|
|
+ entityFieldMapSbBo.append("\n");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // COMMENT ON COLUMN "public"."mast_user"."user_cd" IS '111';
|
|
|
+ // 处理是否为主键
|
|
|
+ if ("1".equalsIgnoreCase(isPrimaryKey)) {
|
|
|
+ hasPrimaryKey = true;
|
|
|
+ primaryKeyColumn = fieldName;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理是否为查询code
|
|
|
+ if ("1".equalsIgnoreCase(isSeachCode)) {
|
|
|
+ searchField = fieldName;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理是否允许为空 (PostgreSQL 中 NOT NULL 约束)
|
|
|
+ if ("NO".equalsIgnoreCase(isNullable)) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理默认值
|
|
|
+ if (defaultValue != null && !defaultValue.trim().isEmpty()) {
|
|
|
+ // 对字符串类型默认值加单引号,数字和函数不加
|
|
|
+ if (needsQuotesForDefault(fieldType)) {
|
|
|
+// fieldDefinition.append(" DEFAULT '").append(defaultValue).append("'");
|
|
|
+ } else {
|
|
|
+// fieldDefinition.append(" DEFAULT ").append(defaultValue);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ResultMap构建
|
|
|
+ resultMapColumnSb.append(" <result property=") .append("\"").append(camelFieldName).append("\"").append(" column=") .append("\"").append(fieldName).append("\"").append("/>\n");
|
|
|
+
|
|
|
+ // Select Filed 构建
|
|
|
+ if(!fieldGenerateLst.contains(fieldName)) {
|
|
|
+
|
|
|
+ selectFieldMapColumnSb.append(" ").append(fieldName).append(",\n");
|
|
|
+ if ("varchar".equalsIgnoreCase(fieldType) && !fieldLength.isEmpty()) {
|
|
|
+ // Select List 构建
|
|
|
+ selectListMapColumnSb.append(" <if test=") .append("\"").append(camelFieldName).append(" != null and ").append(camelFieldName).append(" != ").append("\'").append("\'") .append("\"").append(">\n");
|
|
|
+ } else {
|
|
|
+ selectListMapColumnSb.append(" <if test=") .append("\"").append(camelFieldName).append(" != null ").append("\"").append(">\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ selectListMapColumnSb.append(" and ").append(fieldName).append(" = #{").append(camelFieldName).append("}\n");
|
|
|
+ selectListMapColumnSb.append(" </if>\n");
|
|
|
+ }
|
|
|
+ if(primaryKeyColumn.equals(fieldName)) {
|
|
|
+ selectByIdMapColumnSb.append(fieldName).append(" = #{").append(camelFieldName).append("}\n");
|
|
|
+ }
|
|
|
+ // Insert 构建
|
|
|
+ insertBeforeMapColumnSb.append(" <if test=") .append("\"").append(camelFieldName).append(" != null").append("\"").append(">\n");
|
|
|
+ insertBeforeMapColumnSb.append(" ").append(fieldName).append(",\n");;
|
|
|
+ insertBeforeMapColumnSb.append(" </if>\n");
|
|
|
+ insertAfterMapColumnSb.append(" <if test=") .append("\"").append(camelFieldName).append(" != null").append("\"").append(">\n");
|
|
|
+ insertAfterMapColumnSb.append(" #{").append(camelFieldName).append("},\n");;
|
|
|
+ insertAfterMapColumnSb.append(" </if>\n");
|
|
|
+ // Update 构建
|
|
|
+ updateMapColumnSb.append(" <if test=") .append("\"").append(camelFieldName).append(" != null").append("\"").append(">\n");
|
|
|
+ updateMapColumnSb.append(" ") .append(fieldName).append(" = #{").append(camelFieldName).append("},\n");;
|
|
|
+ updateMapColumnSb.append(" </if>\n");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ jsonFieldMapSb.append("\"").append(camelFieldName).append("\"").append(":");
|
|
|
+ if (("integer".equalsIgnoreCase(fieldType)|| "decimal".equalsIgnoreCase(fieldType)) && !fieldLength.isEmpty()) {
|
|
|
+ jsonFieldMapSb.append(0).append(",\n");
|
|
|
+ } else {
|
|
|
+ jsonFieldMapSb.append("\"").append("\"").append(",\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ jsonMessageMapSb.append("label.").append(camelFieldName).append("=").append(fieldComment).append("\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建完整的 Mapper 语句
|
|
|
+ if (resultMapColumnSb.length() > 0) {
|
|
|
+ // 创建MapBuilder类
|
|
|
+ StringBuilder createMapperSb= new StringBuilder();
|
|
|
+
|
|
|
+ String tableReslut = camelTableName2 + "Result";
|
|
|
+ // 创建Result类
|
|
|
+ StringBuilder resultMapSb = new StringBuilder();
|
|
|
+ createMapperSb.append("<?xml version=") .append("\"").append("1.0").append("\"").append(" encoding=").append("\"").append("UTF-8").append("\"").append(" ?>").append("\n");
|
|
|
+ createMapperSb.append("<!DOCTYPE mapper").append("\n");
|
|
|
+ createMapperSb.append(" PUBLIC ") .append("\"").append("-//mybatis.org//DTD Mapper 3.0//EN").append("\"").append("\n");
|
|
|
+ createMapperSb.append(" ") .append("\"").append("http://mybatis.org/dtd/mybatis-3-mapper.dtd").append("\"").append(">\n");
|
|
|
+ createMapperSb.append("<mapper namespace=") .append("\"").append("jp.yamoto.farm.xxx.xxx.xxx.mapper.").append(camelTableName2).append("Mapper").append("\"").append(">\n");
|
|
|
+
|
|
|
+ // 创建Result类
|
|
|
+ resultMapSb.append(" <resultMap type=") .append("\"").append(camelTableName2).append("\"").append(" id=") .append("\"").append(tableReslut).append("\"").append(">\n");
|
|
|
+ resultMapSb.append(resultMapColumnSb.toString()).append("\n");
|
|
|
+ // Result结尾
|
|
|
+ resultMapSb.append(" </resultMap>");
|
|
|
+ // 添加Result结构
|
|
|
+ createMapperSb.append(resultMapSb.toString()).append("\n");
|
|
|
+
|
|
|
+ // Select Field
|
|
|
+ StringBuilder selectFieldMapSb = new StringBuilder();
|
|
|
+ StringBuilder selectFieldVoSb = new StringBuilder();
|
|
|
+ selectFieldVoSb.append("select").append(camelTableName2).append("Vo");
|
|
|
+ selectFieldMapSb.append(" <sql id=") .append("\"").append(selectFieldVoSb.toString()).append("\"").append(">\n");
|
|
|
+ selectFieldMapSb.append(" select").append("\n");;
|
|
|
+ // 移除最后一个逗号
|
|
|
+ String selectFieldDefs = selectFieldMapColumnSb.toString();
|
|
|
+ if (selectFieldDefs.endsWith(",\n")) {
|
|
|
+ selectFieldDefs = selectFieldDefs.substring(0, selectFieldDefs.length() - 2);
|
|
|
+ }
|
|
|
+ selectFieldMapSb.append(selectFieldDefs).append("\n");;
|
|
|
+ selectFieldMapSb.append(" from ").append(tableName).append("\n");
|
|
|
+ selectFieldMapSb.append(" </sql>");
|
|
|
+ // 添加Select Field 结构
|
|
|
+ createMapperSb.append(selectFieldMapSb.toString()).append("\n");
|
|
|
+
|
|
|
+ // Select List
|
|
|
+ StringBuilder selectListMapSb = new StringBuilder();
|
|
|
+ selectListMapSb.append(" <select id=\"selectList\" parameterType=") .append("\"").append(camelTableName2).append("\"").append(" resultMap=") .append("\"").append(tableReslut).append("\"").append(">\n");
|
|
|
+ selectListMapSb.append(" <include refid=") .append("\"").append(selectFieldVoSb.toString()).append("\"").append("/>\n");
|
|
|
+ selectListMapSb.append(" <where>") .append("\n");
|
|
|
+ selectListMapSb.append(selectListMapColumnSb.toString()).append("\n");
|
|
|
+ selectListMapSb.append(" </where>") .append("\n");
|
|
|
+ selectListMapSb.append(" </select>") .append("\n");
|
|
|
+ // 添加Select List 结构
|
|
|
+ createMapperSb.append(selectListMapSb.toString()).append("\n");
|
|
|
+
|
|
|
+ // Select By Id
|
|
|
+ StringBuilder selectByIdMapSb = new StringBuilder();
|
|
|
+ selectByIdMapSb.append(" <select id=\"selectById\" parameterType=\"String\" ") .append(" resultMap=") .append("\"").append(tableReslut).append("\"").append(">\n");
|
|
|
+ selectByIdMapSb.append(" <include refid=") .append("\"").append(selectFieldVoSb.toString()).append("\"").append("/>\n");
|
|
|
+ selectByIdMapSb.append(" where ").append(selectByIdMapColumnSb.toString()).append("\n");
|
|
|
+ selectByIdMapSb.append(" </select>") .append("\n");
|
|
|
+ // 添加Select By Id 结构
|
|
|
+ createMapperSb.append(selectByIdMapSb.toString()).append("\n");
|
|
|
+
|
|
|
+ // Insert
|
|
|
+ StringBuilder insertMapSb = new StringBuilder();
|
|
|
+ insertMapSb.append(" <insert id=\"insert\" parameterType=\"").append(camelTableName2).append("\"").append(">\n");
|
|
|
+ insertMapSb.append(" insert into ").append(tableName) .append("\n");
|
|
|
+ insertMapSb.append(" <trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">") .append("\n");
|
|
|
+ insertMapSb.append(insertBeforeMapColumnSb.toString()).append("\n");
|
|
|
+ insertMapSb.append(" </trim>") .append("\n");
|
|
|
+ insertMapSb.append(" <trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\">") .append("\n");
|
|
|
+ insertMapSb.append(insertAfterMapColumnSb.toString()).append("\n");
|
|
|
+ insertMapSb.append(" </trim>") .append("\n");
|
|
|
+ insertMapSb.append(" </insert>") .append("\n");
|
|
|
+ // 添加Insert 结构
|
|
|
+ createMapperSb.append(insertMapSb.toString()).append("\n");
|
|
|
+
|
|
|
+ // Insert
|
|
|
+ StringBuilder updateMapSb = new StringBuilder();
|
|
|
+ updateMapSb.append(" <update id=\"update\" parameterType=\"").append(camelTableName2).append("\"").append(">\n");
|
|
|
+ updateMapSb.append(" update ").append(tableName) .append("\n");
|
|
|
+ updateMapSb.append(" <trim prefix=\"SET\" suffixOverrides=\",\">") .append("\n");
|
|
|
+ updateMapSb.append(updateMapColumnSb.toString()).append("\n");
|
|
|
+ updateMapSb.append(" </trim>") .append("\n");
|
|
|
+ updateMapSb.append(" where") .append("\n");
|
|
|
+ updateMapSb.append(" ").append(selectByIdMapColumnSb.toString()).append("\n");
|
|
|
+ updateMapSb.append(" and version = #{version}") .append("\n");
|
|
|
+ updateMapSb.append(" </update>") .append("\n");
|
|
|
+ // 添加Update 结构
|
|
|
+ createMapperSb.append(updateMapSb.toString()).append("\n");
|
|
|
+
|
|
|
+ // Delete
|
|
|
+ StringBuilder deleteMapSb = new StringBuilder();
|
|
|
+ deleteMapSb.append(" <delete id=\"deleteById\" parameterType=\"String\"").append(">\n");
|
|
|
+ deleteMapSb.append(" delete") .append("\n");
|
|
|
+ deleteMapSb.append(" from") .append("\n");
|
|
|
+ deleteMapSb.append(" ").append(tableName) .append("\n");
|
|
|
+ deleteMapSb.append(" where") .append("\n");
|
|
|
+ deleteMapSb.append(" ").append(selectByIdMapColumnSb.toString()).append("\n");
|
|
|
+ deleteMapSb.append(" </delete>") .append("\n");
|
|
|
+ // 添加Delete 结构
|
|
|
+ createMapperSb.append(deleteMapSb.toString()).append("\n");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 文件结尾
|
|
|
+ createMapperSb.append(" </mapper>");
|
|
|
+
|
|
|
+ mapperContent.append(createMapperSb);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建完整的 Mapper 语句
|
|
|
+ if (entityFieldMapSb.length() > 0) {
|
|
|
+ StringBuilder createSb= new StringBuilder();
|
|
|
+ createSb.append("package jp.yamoto.farm.xx.xxx.xxxx.domain.entity;").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+ createSb.append("import jp.yamoto.farm.common.core.domain.BaseEntity;").append("\n");
|
|
|
+ createSb.append("import lombok.Data;").append("\n");
|
|
|
+ createSb.append("import lombok.EqualsAndHashCode;").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+ createSb.append("import java.io.Serial;").append("\n");
|
|
|
+
|
|
|
+ createSb.append("import java.math.BigDecimal;").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ createSb.append("/**").append("\n");
|
|
|
+ createSb.append(" * ").append(tablrNameHanzi).append(" (").append(tableName).append(")") .append("\n");
|
|
|
+ createSb.append(" *").append("\n");
|
|
|
+ createSb.append(" * @author nextosd").append("\n");
|
|
|
+ createSb.append(" */").append("\n");
|
|
|
+ createSb.append("@EqualsAndHashCode(callSuper = true)").append("\n");
|
|
|
+ createSb.append("@Data").append("\n");
|
|
|
+ createSb.append("public class ").append(camelTableName2);
|
|
|
+ createSb.append(" extends BaseEntity {").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ createSb.append(" @Serial").append("\n");
|
|
|
+ createSb.append(" private static final long serialVersionUID = 1L;").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ createSb.append(entityFieldMapSb.toString());
|
|
|
+
|
|
|
+ createSb.append(" /**").append("\n");
|
|
|
+ createSb.append(" * ").append("リビジョン") .append("\n");
|
|
|
+ createSb.append(" */").append("\n");
|
|
|
+ createSb.append(" private Integer version;").append("\n");;
|
|
|
+
|
|
|
+ createSb.append("}").append("\n");
|
|
|
+ entityContent.append(createSb);
|
|
|
+
|
|
|
+ StringBuilder createSb1= new StringBuilder();
|
|
|
+ createSb1.append("package jp.yamoto.farm.xx.xxx.xxxx.domain.entity;").append("\n");
|
|
|
+ createSb1.append("\n");
|
|
|
+ createSb1.append("import jp.yamoto.farm.common.core.domain.BaseEntity;").append("\n");
|
|
|
+ createSb1.append("import lombok.Data;").append("\n");
|
|
|
+ createSb1.append("import lombok.EqualsAndHashCode;").append("\n");
|
|
|
+ createSb1.append("\n");
|
|
|
+ createSb1.append("import java.io.Serial;").append("\n");
|
|
|
+
|
|
|
+ createSb1.append("import java.math.BigDecimal;").append("\n");
|
|
|
+ createSb1.append("\n");
|
|
|
+
|
|
|
+ createSb1.append("/**").append("\n");
|
|
|
+ createSb1.append(" * ").append(tablrNameHanzi).append("詳細情報Vo") .append("\n");
|
|
|
+ createSb1.append(" *").append("\n");
|
|
|
+ createSb1.append(" * @author nextosd").append("\n");
|
|
|
+ createSb1.append(" */").append("\n");
|
|
|
+ createSb1.append("@Data").append("\n");
|
|
|
+ createSb1.append("public class ").append(camelTableName2).append("Vo");
|
|
|
+ createSb1.append(" extends BaseEntity {").append("\n");
|
|
|
+ createSb1.append("\n");
|
|
|
+
|
|
|
+
|
|
|
+ createSb1.append(entityFieldMapSb.toString());
|
|
|
+
|
|
|
+ createSb1.append(" /**").append("\n");
|
|
|
+ createSb1.append(" * ").append("リビジョン") .append("\n");
|
|
|
+ createSb1.append(" */").append("\n");
|
|
|
+ createSb1.append(" private Integer version;").append("\n");;
|
|
|
+
|
|
|
+ createSb1.append("}").append("\n");
|
|
|
+ entityContentVo.append(createSb1);
|
|
|
+
|
|
|
+ StringBuilder createSbBo= new StringBuilder();
|
|
|
+ createSbBo.append("package jp.yamoto.farm.xx.xxx.xxxx.domain.entity;").append("\n");
|
|
|
+ createSbBo.append("\n");
|
|
|
+ createSbBo.append("import jp.yamoto.farm.common.validator.annotation.*;").append("\n");
|
|
|
+ createSbBo.append("import jp.yamoto.farm.common.validator.enums.CheckTypeEnum;").append("\n");
|
|
|
+ createSbBo.append("import jp.yamoto.farm.common.validator.utils.ValidatorGroup;").append("\n");
|
|
|
+ createSbBo.append("import lombok.Data;").append("\n");
|
|
|
+ createSbBo.append("\n");
|
|
|
+ createSbBo.append("import java.io.Serial;").append("\n");
|
|
|
+ createSbBo.append("import java.io.Serializable;").append("\n");
|
|
|
+ createSbBo.append("import java.math.BigDecimal;").append("\n");
|
|
|
+ createSbBo.append("\n");
|
|
|
+
|
|
|
+ createSbBo.append("/**").append("\n");
|
|
|
+ createSbBo.append(" * ").append(tablrNameHanzi).append(" サービスパラメータ対象") .append("\n");
|
|
|
+ createSbBo.append(" *").append("\n");
|
|
|
+ createSbBo.append(" * @author nextosd").append("\n");
|
|
|
+ createSbBo.append(" */").append("\n");
|
|
|
+ createSbBo.append("@Data").append("\n");
|
|
|
+ createSbBo.append("public class ").append(camelTableName2);
|
|
|
+ createSbBo.append("Bo implements Serializable {").append("\n");
|
|
|
+ createSbBo.append("\n");
|
|
|
+
|
|
|
+ createSbBo.append(" @Serial").append("\n");
|
|
|
+ createSbBo.append(" private static final long serialVersionUID = 1L;").append("\n");
|
|
|
+ createSbBo.append("\n");
|
|
|
+
|
|
|
+ createSbBo.append(entityFieldMapSbBo.toString());
|
|
|
+
|
|
|
+ createSbBo.append(" /**").append("\n");
|
|
|
+ createSbBo.append(" * ").append("リビジョン") .append("\n");
|
|
|
+ createSbBo.append(" */").append("\n");
|
|
|
+ createSbBo.append(" private Integer version;").append("\n");;
|
|
|
+
|
|
|
+ createSbBo.append("}").append("\n");
|
|
|
+ entityContentBo.append(createSbBo);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建完整的 Inteface 语句
|
|
|
+ if (resultMapColumnSb.length() > 0) {
|
|
|
+
|
|
|
+ StringBuilder createSb= new StringBuilder();
|
|
|
+ createSb.append("package jp.yamoto.farm.xx.xxx.xxxx.mapper;").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+ createSb.append("import jp.yamoto.farm.xx.xxx.xxxx.domain.entity.").append(camelTableName2).append(";\n");
|
|
|
+ createSb.append("import jp.yamoto.farm.xx.xxx.xxxx.domain.vo.").append(camelTableName2).append("Vo").append(";\n");
|
|
|
+
|
|
|
+ createSb.append("import java.util.List;").append("\n");
|
|
|
+ createSb.append("import lombok.EqualsAndHashCode;").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ createSb.append("/**").append("\n");
|
|
|
+ createSb.append(" * ").append(tablrNameHanzi).append(" Mapperインタフェース") .append("\n");
|
|
|
+ createSb.append(" *").append("\n");
|
|
|
+ createSb.append(" * @author nextosd").append("\n");
|
|
|
+ createSb.append(" */").append("\n");
|
|
|
+
|
|
|
+ createSb.append("public interface ").append(camelTableName2);
|
|
|
+ createSb.append("Mapper {").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ // 检索byID
|
|
|
+ createSb.append(" /**").append("\n");
|
|
|
+ createSb.append(" *").append(tablrNameHanzi).append("を検索") .append("\n");
|
|
|
+ createSb.append(" *").append("\n");
|
|
|
+ createSb.append(" * @param id ").append(tablrNameHanzi).append("プライマリ・キー") .append("\n");
|
|
|
+ createSb.append(" * @return ").append(tablrNameHanzi) .append("\n");
|
|
|
+ createSb.append(" */").append("\n");
|
|
|
+ createSb.append(" public ").append(camelTableName2).append("Vo");
|
|
|
+ createSb.append(" selectById(String id);").append("\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ // 检索List by entity
|
|
|
+ createSb.append(" /**").append("\n");
|
|
|
+ createSb.append(" *").append(tablrNameHanzi).append("を検索リスト") .append("\n");
|
|
|
+ createSb.append(" *").append("\n");
|
|
|
+ createSb.append(" * @param ").append(camelTableName).append(" ").append(tablrNameHanzi) .append("\n");
|
|
|
+ createSb.append(" * @return ").append(tablrNameHanzi).append("リスト") .append("\n");
|
|
|
+ createSb.append(" */").append("\n");
|
|
|
+ createSb.append(" public List<").append(camelTableName2).append("Vo");
|
|
|
+ createSb.append("> selectList(").append(camelTableName2).append(" ").append(camelTableName) .append(");\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ // Insert
|
|
|
+ createSb.append(" /**").append("\n");
|
|
|
+ createSb.append(" *").append(tablrNameHanzi).append("を登録") .append("\n");
|
|
|
+ createSb.append(" *").append("\n");
|
|
|
+ createSb.append(" * @param ").append(camelTableName).append(" ").append(tablrNameHanzi) .append("\n");
|
|
|
+ createSb.append(" * @return ").append(" 結果") .append("\n");
|
|
|
+ createSb.append(" */").append("\n");
|
|
|
+ createSb.append(" public int insert(").append(camelTableName2);
|
|
|
+ createSb.append(" ").append(camelTableName) .append(");\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+ // Update
|
|
|
+ createSb.append(" /**").append("\n");
|
|
|
+ createSb.append(" *").append(tablrNameHanzi).append("を修正") .append("\n");
|
|
|
+ createSb.append(" *").append("\n");
|
|
|
+ createSb.append(" * @param ").append(camelTableName).append(" ").append(tablrNameHanzi) .append("\n");
|
|
|
+ createSb.append(" * @return ").append(" 結果") .append("\n");
|
|
|
+ createSb.append(" */").append("\n");
|
|
|
+ createSb.append(" public int update(").append(camelTableName2);
|
|
|
+ createSb.append(" ").append(camelTableName) .append(");\n");
|
|
|
+ createSb.append("\n");
|
|
|
+
|
|
|
+
|
|
|
+ createSb.append("}").append("\n");
|
|
|
+ intefaceContent.append(createSb.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ generateBuilder.put("mapper", mapperContent);
|
|
|
+ generateBuilder.put("entity", entityContent);
|
|
|
+ generateBuilder.put("entityVo", entityContentVo);
|
|
|
+ generateBuilder.put("entityBo", entityContentBo);
|
|
|
+ generateBuilder.put("inteface", intefaceContent);
|
|
|
+
|
|
|
+ generateBuilder.put("json", jsonFieldMapSb);
|
|
|
+ generateBuilder.put("message",jsonMessageMapSb);
|
|
|
+ return generateBuilder;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据文件扩展名创建合适的Workbook对象
|
|
|
+ */
|
|
|
+ private static Workbook getWorkbook(FileInputStream fis, String filePath) throws IOException {
|
|
|
+ if (filePath.endsWith(".xlsx")) {
|
|
|
+ return new XSSFWorkbook(fis);
|
|
|
+ } else if (filePath.endsWith(".xls")) {
|
|
|
+ return new HSSFWorkbook(fis);
|
|
|
+ } else {
|
|
|
+ throw new IllegalArgumentException("不支持的文件格式");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 安全获取单元格的字符串值,处理不同类型单元格[6,7](@ref)
|
|
|
+ */
|
|
|
+ private static String getCellValueSafe(Cell cell) {
|
|
|
+ if (cell == null) {
|
|
|
+ return ""; // 如果单元格为空,返回空字符串
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (cell.getCellType()) {
|
|
|
+ case STRING:
|
|
|
+ return cell.getStringCellValue().trim();
|
|
|
+ case NUMERIC:
|
|
|
+ // 判断是否为日期
|
|
|
+ if (DateUtil.isCellDateFormatted(cell)) {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ return sdf.format(cell.getDateCellValue());
|
|
|
+ } else {
|
|
|
+ // 处理数字,避免显示为科学计数法
|
|
|
+ double num = cell.getNumericCellValue();
|
|
|
+ if (num == (long) num) {
|
|
|
+ return String.valueOf((long) num); // 整数去除小数点
|
|
|
+ } else {
|
|
|
+ return String.valueOf(num);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ case BOOLEAN:
|
|
|
+ return String.valueOf(cell.getBooleanCellValue());
|
|
|
+ case FORMULA:
|
|
|
+ // 对于公式单元格,尝试计算公式结果,然后递归调用本方法
|
|
|
+ try {
|
|
|
+ FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
|
|
|
+ CellValue cellValue = evaluator.evaluate(cell);
|
|
|
+ // 根据公式计算结果类型再次处理
|
|
|
+ switch (cellValue.getCellType()) {
|
|
|
+ case STRING:
|
|
|
+ return cellValue.getStringValue();
|
|
|
+ case NUMERIC:
|
|
|
+ return String.valueOf(cellValue.getNumberValue()).replace(".0", "");
|
|
|
+ case BOOLEAN:
|
|
|
+ return String.valueOf(cellValue.getBooleanValue());
|
|
|
+ default:
|
|
|
+ return "FORMULA_RESULT_UNKNOWN";
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 如果公式计算失败,退回直接读取公式字符串或缓存值
|
|
|
+ return cell.getCellFormula();
|
|
|
+ }
|
|
|
+ case BLANK:
|
|
|
+ return "";
|
|
|
+ default:
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 辅助方法:处理公式单元格的计算值[6](@ref)
|
|
|
+ */
|
|
|
+ private static Cell getCellValueFromFormula(Cell cell) {
|
|
|
+ // 这里可以引入 FormulaEvaluator 来计算公式结果[6](@ref)
|
|
|
+ // 简化处理:返回单元格的缓存值或尝试计算
|
|
|
+ return cell; // 实际应用中应使用 FormulaEvaluator
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isEmptyRow(Row row) {
|
|
|
+ for (int i = 0; i < row.getLastCellNum(); i++) {
|
|
|
+ Cell cell = row.getCell(i);
|
|
|
+ if (cell != null && cell.getCellType() != CellType.BLANK) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断该数据类型的默认值是否需要引号(字符串、日期等需要)
|
|
|
+ */
|
|
|
+ private static boolean needsQuotesForDefault(String fieldType) {
|
|
|
+ if (fieldType == null) return false;
|
|
|
+ String typeLower = fieldType.toLowerCase();
|
|
|
+ return typeLower.contains("char") || typeLower.contains("text") ||
|
|
|
+ typeLower.contains("date") ;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String convertToCamelCase(String input) {
|
|
|
+ if (input == null || input.isEmpty()) {
|
|
|
+ return input;
|
|
|
+ }
|
|
|
+ StringBuilder result = new StringBuilder();
|
|
|
+ // 使用标志位判断是否需要大写下一个字符[7](@ref)
|
|
|
+ boolean nextUpperCase = false;
|
|
|
+
|
|
|
+ for (int i = 0; i < input.length(); i++) {
|
|
|
+ char currentChar = input.charAt(i);
|
|
|
+ if (currentChar == '_') {
|
|
|
+ nextUpperCase = true; // 遇到下划线,标记下一个字符大写
|
|
|
+ } else {
|
|
|
+ if (nextUpperCase) {
|
|
|
+ result.append(Character.toUpperCase(currentChar));
|
|
|
+ nextUpperCase = false;
|
|
|
+ } else {
|
|
|
+ result.append(currentChar);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String convertToPascalCase(String input) {
|
|
|
+ if (input == null || input.isEmpty()) {
|
|
|
+ return input;
|
|
|
+ }
|
|
|
+ StringBuilder result = new StringBuilder();
|
|
|
+ String[] words = input.split("_");
|
|
|
+
|
|
|
+ for (String word : words) {
|
|
|
+ if (!word.isEmpty()) { // 避免连续下划线导致空字符串
|
|
|
+ // 将每个单词的首字母大写,其余字母小写
|
|
|
+ result.append(Character.toUpperCase(word.charAt(0)))
|
|
|
+ .append(word.substring(1).toLowerCase());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result.toString();
|
|
|
+ }
|
|
|
+}
|