当前位置:网站首页>项目实训12——解析建表的SQL语句
项目实训12——解析建表的SQL语句
2022-06-10 22:01:00 【ScarlettWX】
管理员可以在管理员端新建存储用户信息的数据库并建表,也可以选定已有的用户数据库来建表。之前的界面是让管理员先确定有哪些列,然后为这些列填写中文名和中文描述以及选定类型。这里的创建表不是很灵活,不能随意选择字段长度而且不能建立多个主键和外键。新迭代的功能为允许管理员使用SQL语句建表。调用SQL语句并不难,但是系统数据库需要存储新建表的字段名、类型及介绍,难点在于如何分解SQL语句得到字段名和字段类型。
SQL语句以String类型存在,建表语句中可能会有多个空格,所以用空格作为分割符不能成功拆分字段名和字段类型,而且可能还有类似“primary key”、“aoto_increment”、“not null”等补充属性扰乱第一列和第二列的分割。我想到最后还是需要工具包介入才能实现建表SQL的分解。网上几乎没有分解建表语句的教程,我根据一个分解select语句的教程编写了分解create语句的代码。项目需要引入druid包的依赖,使用这个包的类和方法分解SQL。依赖代码如下:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
项目的application.properties也需要更改:
server.port=8080
spring.datasource.name==druid
spring.datasource.type= com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.url=jdbc:mysql://localhost:3306/databaseName?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=xxxxxxxx
spring.datasource.druid.filters=stat
首先明确我想获得的是create table语句中的字段名和相应的字段类型以及字段描述。druid包中有对应不同类型SQL语句的类,比如新建数据库语句应使用SQLCreateDatabaseStatement类型,删除索引表语句应使用SQLDropIndexStatement类型,新建表应使用SQLCreateTableStatement类型,使用不对应的类型不会解析出正确的结果。我一开始就是按照解析select语句的教程使用错了对象,一直没有解析出字段名和类型。而且druid包也可以解析不同数据库的语句,这一点也要注意,不同数据库的SQL语句有些许的语法差异。解析的第一步要先声明一个SQLStatementParser类型的对象parser,我使用的是MySQL数据库,所以new出的子类型是MySqlStatementParser。第二步声明一个SQLCreateTableStatement对象sqlCreateTableStatement等于parser.parseCreateTable()。parser调用的方法也是对应create table类型的语句,其他操作要使用对应的parse方法。第三步声明一个SQLObject类型的List对象sqlObjects存储sqlCreateTableStatement的子对象,这些子对象就存储了每个字段的信息。然后使用一个for循环处理sqlObjects中每一个子对象。获取具体信息之前先判断sqlObjects实例化之后是否为SQLColumnDefinition类型,即列定义对象。如果是,则通过columnDefinition.getNameAsString()获得字段名,columnDefinition.getDataType().getName()获得字段类型,(String) ((SQLCharExpr) columnDefinition.getComment()).getValue()获得字段描述。注意这时的字段类型不包括括号内的字段长度。使用((SQLIntegerExpr) arguments.get(0)).getNumber().toString()获得字段的长度,再通过字符串拼接获得完整的字段类型。获得的信息存在一个meta对象,循环的一个meta类型的List对象。再循环执行插入DBID_CID_META表的操作。这样就完成了解析建表SQL语句的操作。具体代码如下:
public void assembleMeta(List<Meta> metaList, String sql) {
SQLStatementParser parser = new MySqlStatementParser(sql);
SQLCreateTableStatement sqlCreateTableStatement=parser.parseCreateTable();
List<SQLObject> sqlObjects = sqlCreateTableStatement.getChildren();
for (SQLObject sqlObject : sqlObjects) {
if (sqlObject instanceof SQLColumnDefinition) {
SQLColumnDefinition columnDefinition = ((SQLColumnDefinition) sqlObject);
Meta meta=new Meta();
meta.setEN(columnDefinition.getNameAsString());
System.out.println("从SQL中获得的字段名:"+meta.getEN());
String metaType=columnDefinition.getDataType().getName();
List<SQLExpr> arguments = columnDefinition.getDataType().getArguments();
if (!CollectionUtils.isEmpty(arguments)) {
metaType=metaType+"("+((SQLIntegerExpr) arguments.get(0)).getNumber().toString()+")";
}
meta.setCN(metaType);
System.out.println("从SQL中获得的字段类型:"+meta.getCN());
if (columnDefinition.getComment() != null) {
meta.setDes((String) ((SQLCharExpr) columnDefinition.getComment()).getValue());
System.out.println("从SQL中获得的字段描述:"+meta.getDes());
}else{
meta.setDes("暂无介绍!");
System.out.println("从SQL中获得的字段描述:"+meta.getDes());
}
meta.setZhengze("F");
metaList.add(meta);
}else{
System.out.println("类型还是不对!");
}
}
}
controller层的调用代码:
@ResponseBody
@RequestMapping(value = "/createSQL",method = RequestMethod.POST)
public Map<String, Object> createSQL(HttpServletRequest req) throws SQLException {
Map<String, Object> map = new HashMap<>();
int DBid =Integer.parseInt(req.getParameter("DBid").trim());
System.out.println("用户数据库编号:"+DBid);
int Cid =Integer.parseInt(req.getParameter("Cid").trim());
System.out.println("新建的表编号:"+Cid);
String sql =req.getParameter("sql").trim();
int ctsql=chartService.sqlCreateTable(DBid,sql);
System.out.println("在用户数据库建表成功!");
List<Meta> metaList=new ArrayList<>();
getFromSQL g=new getFromSQL();
g.assembleMeta(metaList,sql);
int [] um=new int[metaList.size()];
int judge=0;
for(int i=0; i<metaList.size(); i++){
um[i]=metaService.insertMeta(DBid,Cid,metaList.get(i).getEN(),metaList.get(i).getCN(),metaList.get(i).getDes());
System.out.println("um["+i+"]="+um[i]);
if(um[i]!=0)
judge=1;
}
if (ctsql==0&&judge==0) {
map.put("state", true);
map.put("msg", "使用SQL建表成功!");
} else {
map.put("state", false);
map.put("msg", "建表失败!请检查SQL语句语法问题!");
}
return map;
}
边栏推荐
- Html+php+mysql login registration page
- [raise bar C #] how to call the base of the interface
- 通达信股票开户安全吗?如何办理开户呢?
- 【GMM+KDE】基于MATLAB的GMM和KDE核估计得目标跟踪仿真
- Sherri Monroe被任命为增材制造商绿色贸易协会的新任执行董事
- Display of successful cases of target customer matching data table
- Keras深度学习实战(8)——使用数据增强提高神经网络性能
- 数据与信息资源共享平台(四)
- 普通网络摄像头的拉取方法
- Openjudge noi 1.13 15: finding modes in sequences
猜你喜欢

联想首次详解混合云Lenovo xCloud五大优势,如何打造智能化数字底座

【原创】医鹿APP九价HPV数据抓包分析

UE4 getting started with bone animation

Distributed Foundation

Interpreting the registry class of mmcv

Redis from entry to entry

kubernetes多網卡方案之Multus CNI部署和基本使用

数据与信息资源共享平台(八)
![[tcapulusdb knowledge base] tcapulusdb shard relocation introduction](/img/7b/8c4f1549054ee8c0184495d9e8e378.png)
[tcapulusdb knowledge base] tcapulusdb shard relocation introduction

Keras deep learning practice (8) -- using data enhancement to improve neural network performance
随机推荐
[Axi] explain the principle of two-way handshake mechanism of Axi protocol
But it shows that you are the most native zaifkmw in five counties
Bottom layer communication protocol ① of single chip microcomputer -- synchronous and asynchronous, parallel and serial, full duplex and half duplex, simplex, level signal and differential signal
[content co creation] issue 17: summer is hot and you are so sweet! Participating in the signing of Huawei cloud Xiaobian, there is always a pattern gift bag that moves you!
200个C语言单词,请收藏!
How to run Plink software -- three methods
玩电子,穷三代
Can Huawei matepad become the secondary screen of your laptop?
Is it safe for BOC securities to open an account? What is its relationship with the Bank of China?
数据与信息资源共享平台(八)
[tcapulusdb knowledge base] tcapulusdb tcapdb capacity expansion and contraction introduction
Locking mechanism
Question bank and simulation test of 2022 tea artist (intermediate) operation certificate examination
Sentinel
Watlow签订从施耐德电气手中收购Eurotherm的协议
Interpretation of dataset class of mmdetection
Fallback operation in SVN
同花顺开户怎么样?开户安全吗?
MySQL master-slave replication solves read-write separation
Multus CNI deployment and basic use of kubernetes multi network card scheme