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

记录:278

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

版本:Spring Boot 2.6.3

一、案例场景

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

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

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

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

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

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

create table SENSOR_DATA ( 
  ID  NUMBER(16) not null ,
  REGION  VARCHAR2(8),
  VALUE1  NUMBER(16,2),
  VALUE2  NUMBER(16,2)
 );
comment on table  SENSOR_DATA is '传感器数据';
comment on column SENSOR_DATA.ID is '实体唯一标识';
comment on column SENSOR_DATA.REGION is '区域';
comment on column SENSOR_DATA.VALUE1 is '取值1';
comment on column SENSOR_DATA.VALUE2 is '取值2';
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,对集合相关操作。

三、代码

1.读文件

读取文件,逐行读取,每读取一行,立即解析,根据分隔符##,分割成多个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 part1 = "create table ";
 String part2 = tableName;
 String part3 = " ( ";
 writeFile(fileName, part1 + part2 + part3 + "\n");
 String part5 = " );";
 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;
  if (StringUtils.equals("Y", oneLine.get(2))) {
      line = oneLine.get(0) + "  " + oneLine.get(1) + " not null " + "," + "\n";
  } else if (i == last) {
      line = oneLine.get(0) + "  " + oneLine.get(1) + "\n";
  } else {
      line = oneLine.get(0) + "  " + oneLine.get(1) + "," + "\n";
  }
  writeFile(fileName, "  " + line);
 }
 writeFile(fileName, part5 + "\n");
}

4.生成字段注释

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

public static void createComment(String fileName, ArrayList<ArrayList<String>> content) {
  List<String> firstOne = content.get(0);
  String tableName = firstOne.get(0);
  String tableComment = firstOne.get(1);
  String part1 = "comment on table  ";
  String part2 = tableName;
  String part3 = " is '";
  String part4 = tableComment;
  String part5 = "';";
  String tableComments = part1 + part2 + part3 + part4 + part5;
  writeFile(fileName, tableComments + "\n");
  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 part01 = "comment on column ";
    String part02 = tableName + ".";
    String part03 = oneLine.get(0);
    String part04 = " is '";
    String part05 = oneLine.get(3) + "';\n";
    String part = part01 + part02 + part03 + part04 + part05;
    writeFile(fileName, part);
  }
}

5.生成主键约束和索引

根据从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;
}

6.在main函数调用

在main函数调用测试。

public static void main(String[] args) {
  System.out.println("开始...");
  String baseDir = "D:\\example\\";
  String fileName = "SENSOR_DATA";
  String txtFileName = baseDir + fileName + ".txt";
  String sqlFileName = baseDir + fileName + ".sql";
  ArrayList<ArrayList<String>> read = readFromTxt(txtFileName);
  // 表结构
  createTable(sqlFileName, read);
  // 注释
  createComment(sqlFileName, read);
  // 主键和索引(单个字段)
  createPrimaryAndIndex(sqlFileName, read);
  System.out.println("结束...");
}

以上,感谢。

2022年7月1日

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值