使用Java根据约定格式生成MySQL建表语句

记录:279

场景:在实际开发中,开发文档中的建表信息以表格的方式提供,包括字段名称、字段类型、字段注释、是否为空等。本例就是先把表格信息转换为约定格式的txt文件,在使用Java代码生成完整的MySQL建表语句。

版本:Spring Boot 2.6.3

一、案例场景

1.开发文档中以表格方式提供建表信息。

 2.手动转换为txt文件,文件名:SENSOR_DATA.txt,格式约定如下:

第一行为,表名##表名称。

第二行开始,每行:字段名称##字段类型##字段非空##字段注释##字段主键或者索引。

SENSOR_DATA##传感器数据
ID##BIGINT(16)##Y##实体唯一标识##primary
REGION##VARCHAR(8)##N##区域##index
VALUE1##DECIMAL(16,2)##N##取值1##N
VALUE2##DECIMAL(16,2)##N##取值2##N

3.执行代码,自动生成sql文件,文件名:SENSOR_DATA.sql,生成结果。

create table SENSOR_DATA ( 
  ID BIGINT(16)  not null  COMMENT '实体唯一标识',
  REGION VARCHAR(8)  COMMENT '区域',
  VALUE1 DECIMAL(16,2)  COMMENT '取值1',
  VALUE2 DECIMAL(16,2)  COMMENT '取值2'
 ) ENGINE=INNODB DEFAULT CHARSET=utf8  COMMENT='传感器数据';
alter table  SENSOR_DATA add constraint PK_SENSOR_DATA_ID primary key (ID);
create index  IDX_SENSOR_DATA_REGION on SENSOR_DATA (REGION);

二、使用类

1.读文件操作

java.lang.AutoCloseable,接口。

java.io.Closeable,接口,继承AutoCloseable。

java.lang.Readable,接口。

java.io.Reader,抽象类,实现Readable接口和Closeable。

java.io.BufferedReader,实现类,实现Reader抽象类。

java.io.InputStreamReader,实现类,读输入流,Reader抽象类。

java.io.FileReader,实现类,读文件,继承InputStreamReader。

new BufferedReader(new FileReader(fileName))。

2.写文件操作

java.lang.AutoCloseable,接口。

java.io.Closeable,接口,继承AutoCloseable。

java.io.Flushable,接口。

java.lang.Appendable,接口。

java.io.Writer,抽象类,实现Appendable, Closeable, Flushable。

java.io.BufferedWriter,实现类,实现Writer抽象类。

java.io.OutputStreamWriter,实现类,写输出流,Writer抽象类。

java.io.FileWriter,实现类,写文件,继承OutputStreamWriter。

new BufferedWriter(new FileWriter(fileName, true));

3.操作ArrayList

java.lang.Iterable,接口。

java.util.Collection,接口,继承Iterable。

java.util.List,接口,继承Collection。

java.util.AbstractCollection,抽象类,实现Collection。

java.util.AbstractList,抽象类,继承AbstractCollection,实现List。

java.util.ArrayList,一个Resizable-array。

4.Collections

java.util.Collections,对集合相关操作。

5.File操作

java.io.Serializable,接口。

java.lang.Comparable,接口。

java.io.File,实现类,实现Serializable和Comparable接口。

三、代码

1.读文件

读取文件,逐行读取,每读取一行,立即解析,根据分隔符##,分割成多个String字符串,存放在一个List<String>中。解析完成的一行数据List<String>,再放入List<List>中。

读取文件,逐行读取,每读取一行,立即解析,根据分隔符##,分割成多个String字符串,存放在一个List<String>中。解析完成的一行数据List<String>,再放入List<List>中。

public static ArrayList<ArrayList<String>> readFromTxt(String fileName) {
 ArrayList<ArrayList<String>> listAll = new ArrayList<>();
 try {
   //1.读txt文件,一次读一行
   BufferedReader br = new BufferedReader(new FileReader(fileName));
   String oneLine = null;
   //2.使用readLine方法,一次读一行
   while ((oneLine = br.readLine()) != null) {
    ArrayList<String> oneLineList = getOneLine(oneLine, "##");
    listAll.add(oneLineList);
   }
   br.close();
 } catch (Exception e) {
    System.out.println("读异常.");
    e.printStackTrace();
 }
 return listAll;
}
public static ArrayList<String> getOneLine(String content, String split) {
  String[] strArr = content.split(split);
  ArrayList<String> oneLine = new ArrayList<>(strArr.length);
  Collections.addAll(oneLine, strArr);
  return oneLine;
}

2.写文件

逐行写文件,以追加方式写入,不覆盖已经写入的内容。

public static void writeFile(String fileName, String content) {
 try {
   // 设置为追加写入true
   BufferedWriter bw = new BufferedWriter(
           new FileWriter(fileName, true));
   bw.write(content);
   bw.close();
 } catch (IOException e) {
   System.out.println("读异常.");
   e.printStackTrace();
 }
}

3.生成建表语句和注释

根据从txt读取的表字段信息,生成建表语句和注释。

public static void createTable(String fileName, ArrayList<ArrayList<String>> content) {
  List<String> firstOne = content.get(0);
  String tableName = firstOne.get(0);
  String tableComment = firstOne.get(1);
  String part1 = "create table ";
  String part2 = tableName;
  String part3 = " ( ";
  writeFile(fileName, part1 + part2 + part3 + "\n");
  String part5 = " ) " + "ENGINE=INNODB DEFAULT CHARSET=utf8 ";
  String part6 = " COMMENT='" + tableComment + "';";
  int size = content.size();
  for (int i = 0; i < size; i++) {
    ArrayList<String> oneLine = content.get(i);
    if (StringUtils.equals(tableName, oneLine.get(0))) continue;
    String line = "";
    int last = content.size() - 1;
    String columnName = oneLine.get(0) + " ";
    String dataType = oneLine.get(1) + " ";
    String comment = " COMMENT '" + oneLine.get(3) + "'";
    if (StringUtils.equals("Y", oneLine.get(2))) {
        line = columnName + dataType + " not null " + comment + "," + "\n";
    } else if (i == last) {
        line = columnName + dataType + comment + "\n";
    } else {
        line = columnName + dataType + comment + "," + "\n";
    }
    writeFile(fileName, "  " + line);
  }
  writeFile(fileName, part5 + part6 + "\n");
}

4.生成主键约束和索引

根据从txt读取的表字段信息,生成主键约束和索引。

// 生成主键和索引
public static void createPrimaryAndIndex(String fileName, ArrayList<ArrayList<String>> content) {
 List<String> firstOne = content.get(0);
 String tableName = firstOne.get(0);
 int size = content.size();
 for (int i = 0; i < size; i++) {
   ArrayList<String> oneLine = content.get(i);
   if (StringUtils.equals(tableName, oneLine.get(0))) continue;
   if (StringUtils.equals("primary", oneLine.get(4).toLowerCase())) {
     String part1 = "alter table  ";
     String part2 = tableName;
     String part3 = " add constraint ";
     String part4 = "PK_" + tableName + "_" + oneLine.get(0);
     String part5 = " primary key (" + oneLine.get(0) + ");";
     part4 = getLimitString(part4);
     String pk = part1 + part2 + part3 + part4 + part5;
     writeFile(fileName, pk + "\n");
   }
   if (StringUtils.equals("index", oneLine.get(4).toLowerCase())) {
     String part1 = "create index  ";
     String part2 = "IDX_" + tableName + "_" + oneLine.get(0);
     String part3 = " on ";
     String part4 = tableName;
     String part5 = " (" + oneLine.get(0) + ");";
     part2 = getLimitString(part2);
     String index = part1 + part2 + part3 + part4 + part5;
     writeFile(fileName, index + "\n");
   }
 }
}
// 限定主键或索引名称字符串30个字符
public static String getLimitString(String srcStr){
 int length = srcStr.length();
 if (length > 30) {
   srcStr = srcStr.substring(0, 30);
   String underline = srcStr.substring(29, 30);
   if (StringUtils.equals("_", underline)) {
    // 最后一个字符是字母而不是下划线
    srcStr = srcStr.substring(0, 29);
   }
 }
 return srcStr;
}

5.在main函数调用

在main函数调用测试,从指定目录下读取txt文件名称,逐个生成SQL文件。

public static void main(String[] args) {
  System.out.println("开始...");
  String baseDir = "D:\\example\\";
  List<String> listFile = getAllTxtFile(baseDir);
  for (String fileName : listFile) {
      singleFile(baseDir, fileName);
  }
  System.out.println("结束...");
}
public static List<String> getAllTxtFile(String path) {
  File dirFile = new File(path);
  File[] subFiles = dirFile.listFiles();
  List<String> fileList = new ArrayList<>();
  if (subFiles != null) {
   for (File subFile : subFiles) {
    if (subFile.isDirectory()) continue;
    else {
        if (subFile.isFile() && subFile.getName().endsWith(".txt")) {
            fileList.add(subFile.getName().substring(0, subFile.getName().length() - 4));
        }
    }
   }
  }
  return fileList;
}
public static void singleFile(String baseDir, String fileName) {
  String srcFileName = baseDir + fileName + ".txt";
  String tarFileName = baseDir + fileName + ".sql";
  ArrayList<ArrayList<String>> read = readFromTxt(srcFileName);
  // 表结构与注释
  createTable(tarFileName, read);
  // 主键和索引
  createPrimaryAndIndex(tarFileName, read);
}

以上,感谢。

2022年7月2日

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于Spring Boot和EasyExcel的问题。为了回答这个问题,我需要先解释一下Spring Boot和EasyExcel是什么。 Spring Boot是一个基于Spring框架的快速开发框架,它可以帮助开发者更快地搭建Web应用程序。而EasyExcel则是一个用于读写Excel文件的Java库,它可以帮助开发者更轻松地处理Excel文件。 回到你的问题,你想知道如何通过上传Excel文件,使用EasyExcel根据Excel内容生成MySQL建表语句。这个问题可以分成两个步骤来解决: 1. 上传Excel文件 在Spring Boot中,上传文件可以使用Spring MVC中的MultipartResolver来实现。可以在Controller中添加一个方法,使用@RequestParam注解来接收上传的文件,然后将文件保存到本地或者服务器上。 2. 使用EasyExcel生成MySQL建表语句 首先,需要将Excel文件读取到Java中。可以使用EasyExcel提供的读取Excel文件的API来实现。然后,可以遍历Excel文件中的每一行数据,将数据转换为MySQL建表语句,并将建表语句保存到文件或者直接执行。 下面是一个简单的代码示例,用于实现以上功能: ```java // 上传文件 @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file) throws IOException { // 将Excel文件读取到Java中 List<Map<Integer, String>> data = EasyExcel.read(file.getInputStream()).sheet().doReadSync(); // 遍历Excel中的每一行数据 List<String> sqlList = new ArrayList<>(); for (Map<Integer, String> rowData : data) { // 将数据转换为MySQL建表语句 String sql = generateSql(rowData); sqlList.add(sql); } // 将建表语句保存到文件或者直接执行 saveSqlToFile(sqlList); executeSql(sqlList); return "upload success"; } // 生成建表语句 private String generateSql(Map<Integer, String> rowData) { // TODO: 根据Excel中的数据生成MySQL建表语句 return ""; } // 将建表语句保存到文件 private void saveSqlToFile(List<String> sqlList) { // TODO: 将建表语句保存到文件 } // 执行建表语句 private void executeSql(List<String> sqlList) { // TODO: 执行建表语句 } ``` 需要注意的是,以上代码仅提供了一个思路,具体实现需要根据具体的需求进行调整。同时,为了安全起见,建议在处理Excel数据时进行一些校验,避免出现不合法的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值