管理员可以在管理员端新建存储用户信息的数据库并建表,也可以选定已有的用户数据库来建表。之前的界面是让管理员先确定有哪些列,然后为这些列填写中文名和中文描述以及选定类型。这里的创建表不是很灵活,不能随意选择字段长度而且不能建立多个主键和外键。新迭代的功能为允许管理员使用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;}

项目实训12——解析建表的SQL语句相关推荐

  1. Bootstrap4+MySQL前后端综合实训-Day08-AM【多表查询sql语句、关联数据的假删除、自动增长主键的获取、栏目管理“数据编辑”按钮的实现】

    [Bootstrap4前端框架+MySQL数据库]前后端综合实训[10天课程 博客汇总表 详细笔记][附:实训所有代码] 目   录 多表查询sql语句 关联数据的假删除(status状态码/数据可恢 ...

  2. python读取erp的数据库_【ERP系统设计】【数据库设计】对数据表重命名和读取建表的SQL语句...

    今天做了一个小Model,就是把另一数据库中的表复制到目标数据库中,但是复制到目标数据库中的表中的记录为空 思路: 1 读取建表的SQL语句 2 通过jdbc执行 3 对新建表进行重新命名 精要: 1 ...

  3. mysql建库sql语句_mysql建库和建表的sql语句

    需求描述: 在用户提交酒店订单时,需要记录订单信息和订单日志:订单信息包括用户名.订单号.入住时间和离店时间: 订单日志包括谁在什么时候操作了该订单,下订单时需要记录的订单日志为系统在下订单的时间点创 ...

  4. mysql建表用的什么语句_mysql建表常用sql语句个人经验分享

    连接:mysql -h主机地址 -u用户名 -p用户密码 (注:u与root可以不用加空格,其它也一样) 断开:exit (回车) 创建授权:grant select on 数据库.* to 用户名@ ...

  5. 项目实训记录(1-2周)

    前言 我是我们项目实训小队的队长,负责了开题答辩.下面是项目实训1-2周的工作记录. 一.确定选题 我们小组四个同学就选题进行了很长时间的讨论,最后确定选择做一个基于人工智能技术的大学生辅助学习系统. ...

  6. Java程序设计教程与实训_Java程序设计教程与项目实训

    Java程序设计教程与项目实训 编辑 锁定 讨论 上传视频 <Java程序设计教程与项目实训>是2017年8月清华大学出版社出版的图书,作者是温秀梅.司亚超. 书    名 Java程序设 ...

  7. java程序设计教程与项目_Java程序设计教程与项目实训

    书名:Java程序设计教程与项目实训 作者:温秀梅.司亚超 出版社:清华大学出版社 出版日期:2017/8/1 字数: 页数: 版次: ISBN:9787#302473701 定价:49.5 目录 章 ...

  8. 国家开放大学计算机基础实训项目一,国家开放大学电大专科《微机系统与维护》网络课实训11及实训12作业及答案...

    国家开放大学电大专科<微机系统与维护>网络课实训11及实训12作业及答案 实训11 微机软件系统的维护实训报告 实训内容 操作系统维护工具的使用.注册表的维护.Windows优化大师软件的 ...

  9. 视频教程-C++微服务架构及安全云盘项目实训-C/C++

    C++微服务架构及安全云盘项目实训 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真,计算机视觉,嵌入式图像处理,云安全审 ...

  10. 视频教程-JSP从入门到精通2016+在线视频教学平台项目实训-其他

    JSP从入门到精通2016+在线视频教学平台项目实训 19年软件开发经验,设计开发40多个大型软件,10年从事高等教育,主要为java系列课程,带你轻松进入java生涯. 赖国荣 ¥68.00 立即订 ...

最新文章

  1. Android GUI之View测量
  2. 算法博士平均月入4万,数据可视化技能全球吃香 | 2020年《顶级数据团队建设全景报告》重磅发布...
  3. LeetCode_Pascal's Triangle II_杨辉三角形II(Java实现)
  4. 1.18.2.5.Table APISQL(查询表、Table API、SQL、混用Table API和SQL、输出表、翻译与执行查询、Blink planner、Old planner)等
  5. java日期格式精确到分_详解Java日期格式化及其使用例子
  6. 第一章 统计学概论
  7. std::map用法
  8. 链表c语言stl,C++STL之List容器
  9. 把房子交给“我爱我家”后,我都不敢再进去了
  10. [Offer收割]编程练习赛42
  11. 前端开发必备工具之 - TinyPNG
  12. 计算机里面为什么只剩c盘,电脑只剩下C盘了,怎么处理
  13. Centos操作系统:文件的上传、下载、压缩、解压缩
  14. [转]关于公司级别的知识库的建设的一些看法。
  15. 流量来了,去努力保护好你的系统
  16. 【大脑】--如何让大脑快速记忆
  17. Matlab多项式和符号函数简介
  18. 百度今天怎么打不开了
  19. 计算机为什么有网络凭证,Win10访问局域网中计算机共享文件显示需要网络凭证怎么办?...
  20. 火狐浏览器和IE的CSS区别

热门文章

  1. fft和freqz的区别
  2. war压缩命令_ubuntu/linux下打包压缩war、解压war包和jar命令
  3. dtft性质及证明_N第二章离散时间傅立叶变换(DTFT).ppt
  4. 上传,修改头像的使用
  5. vant中修改用户的头像
  6. NVIDIA驱动重装经历
  7. SCT2650,4.5V-60V电压,芯洲降压DCDC转换器,参数
  8. VB开发OCX控件的属性之自定义列表项
  9. MPU9250调试笔记(融合磁力计计算Yaw)
  10. 清算号和联行号有区别吗?区别是什么?