mybatis mapper.xml转建表语句

news2025/1/17 1:01:20

从网上下载了代码,但是发现没有DDL建表语句,只能自己手动创建了,感觉太麻烦,就写了一个工具类

将所有的mapper.xml放入到一个文件夹中,程序会自动读取生成建表语句

依赖的jar

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version>
</dependency>
<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
    <groupId>org.jdom</groupId>
    <artifactId>jdom</artifactId>
    <version>1.1.3</version>
</dependency>

package com.example.demo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
import org.springframework.util.StringUtils;
import org.xml.sax.InputSource;

public class Sqlmap2Table {

    // 默认所有的varchar都是512,可以保证满足绝大多数的字段
    private static final String DEFAULT_VARCHAR_LENGTH = "VARCHAR(256)";


    public static void main(String[] args) throws Exception {
        String sqlMapPath = "C:\\Users\\Administrator\\Downloads\\estate-public-master\\src\\main\\java\\com\\wy\\mapping";//这里指定你的sqlmap配置文件所在路径
        analysis(sqlMapPath);
    }


    /* 根据指定的目录进行遍历分析
    *
    * @param path
    * @throws IOException
    * @throws JDOMException
    */
   private static void analysis(String path) throws IOException, JDOMException {
       File filePath = new File(path);
       if (filePath.isDirectory() && !filePath.getName().equals(".svn")) {
           File[] fileList = filePath.listFiles();
           for (File file : fileList) {
               if (file.isDirectory()) {
                   analysis(file.getAbsolutePath());
               } else {
                   analysisSqlMap(file.getAbsolutePath());
               }
           }
       }
   }


   /**
    * 分析单个的sqlmap配置文件
    *  当然xml文件中必须设置字段类型的属性,否则无法判断字段属性
    * @param sqlMapFile
    * @throws IOException
    * @throws JDOMException
    */
   @SuppressWarnings("unchecked")
   private static void analysisSqlMap(String sqlMapFile) throws IOException, JDOMException {
       // System.out.println("************"+sqlMapFile);
        boolean isNull=false;
       /**
        * 这里要把sqlmap文件中的这一行去掉:<br>
        * <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"><br>
        * 否则JDom根据文件创建Document对象时,会报找不到www.ibatis.com这个异常,导致渲染不成功。
        */
       String xmlString = filterRead(sqlMapFile, "<!DOCTYPE");
//       XmlDocument doc = new XmlDocument();

       Document doc = getDocument(xmlString);
       String tableName = getTableNameByInsert(doc);
       List<Element> resultMap = (List<Element>) XPath.selectNodes(doc, "//resultMap");
       for (Element e : resultMap) {
           if (org.apache.commons.lang3.StringUtils.isBlank(tableName)){
               String alias = e.getAttributeValue("type");
               tableName = getTableName(doc, alias);
           }
           List<Element> children = e.getChildren();
           StringBuilder createTableString = new StringBuilder("create table `" + tableName + "` (\n\t");
           int size = 0;
           boolean isId = false;
           for (Element child : children) {
               String jdbcType = child.getAttributeValue("jdbcType");  //获取属性类型
               if(StringUtils.isEmpty(jdbcType)){
               isNull=true;
               break;
               }
               if (jdbcType.toUpperCase().equals("VARCHAR")) {
                   jdbcType = DEFAULT_VARCHAR_LENGTH;
               }
               else if (jdbcType.toUpperCase().equals("CHAR")) {
                   jdbcType = "char(10)";
               }
               else if (jdbcType.toUpperCase().equals("BIGINT")) {
                   jdbcType = "bigint(20)";
               }
               if (jdbcType.toUpperCase().equals("INTEGER")) {
                   jdbcType = "int(11)";
               }
               else if (jdbcType.toUpperCase().equals("DECIMAL")) {
                   jdbcType = "decimal(10,2)";
               }
               else if (jdbcType.toUpperCase().equals("NUMERIC")) {
                   jdbcType = "decimal(10,2)";
               }
               if (jdbcType.toUpperCase().equals("DOUBLE")) {
                   jdbcType = "double";
               }
               if (jdbcType.toUpperCase().equals("REAL")) {
                   jdbcType = "double";
               }

               if (jdbcType.toUpperCase().equals("BOOLEAN")) {
                   jdbcType = "tinyint(1)";
               }
               if (jdbcType.toUpperCase().equals("FLOAT")) {
                   jdbcType = "float";
               }
               String columnName = child.getAttributeValue("column");
               createTableString.append("`").append(columnName).append("` ").append(jdbcType);  //加入属性和类型
               if ("ID".equalsIgnoreCase(columnName)){
                   createTableString.append(" NOT NULL AUTO_INCREMENT");
                   isId = true;
               }else{
                   createTableString.append(" DEFAULT NULL");
               }

               if (size < children.size() - 1) {
                   createTableString.append(",\n\t");

               }
               size++;
           }
           if(isNull){
               break;
           }
           if (isId){
               createTableString.append(",\n\tPRIMARY KEY (`id`) \n");
           }else{
               createTableString.append("\n");
           }
           createTableString.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
           System.out.println(createTableString.toString().toLowerCase());
       }
   }

    private static String getTableNameByInsert(Document doc) throws JDOMException {
        List<Element> resultMap = (List<Element>) XPath.selectNodes(doc, "//insert");
        for (Element ele : resultMap){
            String text = ele.getText();
            //System.out.println(ele.getText());
            int intoIndex = text.indexOf("into");
            if (intoIndex > 0){
                String s = text.substring(intoIndex+4);
                intoIndex = s.indexOf("(");
                if (intoIndex > 0){
                    s = s.substring(0,intoIndex);
                    return s.trim().toLowerCase();
                }
            }
        }
        return null;
    }




    private static String getTableName(Document doc, String alias) throws JDOMException {
       String tableName = "";
       String classPath = null;
       // 这里的alias可能是一个别名,也可能是一个java类路径,这里我通过该alias是否有点"."这个符号来区别
       if (!alias.contains(".")) {// 是JAVA类
           // 是别名,就到配置的别名中去找
           Element aliasElement = (Element) XPath.selectSingleNode(doc, "//typeAlias[@alias=\"" + alias + "\"]");
           alias = aliasElement.getAttributeValue("type");
       }
        int lastIndex = alias.lastIndexOf(".");
        if (lastIndex > 0) {// 是JAVA类
            classPath = alias.substring(lastIndex+1);
        }else{
            classPath = alias;
        }


      // int i = classPath.lastIndexOf("DO");
       // 取到根据表名生成的DO名称,无“DO”两个字符
       //classPath = classPath.substring(0, i);
       char[] chars = classPath.toCharArray();
       boolean isFirst = Boolean.TRUE;
       // 生成真实的表名
       for (char c : chars) {
           if (!isFirst && c >= 65 && c <= 90) {
               tableName += "_";
           }
           if (isFirst) {
               isFirst = Boolean.FALSE;
           }
           tableName += c;
       }
       // 表名转换为大写返回
       return tableName.toUpperCase();
   }


   /**
    * 过滤性阅读
    *
    * @param filePath 文件路径
    * @param notIncludeLineStartWith 不包括的字符,即某行的开头是这样的字符串,则在读取的时候该行忽略
    * @return
    * @throws IOException
    */
   private static String filterRead(String filePath, String notIncludeLineStartWith) throws IOException {
       String result = "";
       FileReader fr = new FileReader(filePath);
       BufferedReader br = new BufferedReader(fr);
       String line = br.readLine();
       while (line != null) {
           if (!line.startsWith(notIncludeLineStartWith)) {
               result += line;
           }
           line = br.readLine();
           if (line != null && !line.startsWith(notIncludeLineStartWith)) {
               result += "\n";
           }
       }
       br.close();
       fr.close();
       return result;
   }



   /**
    * 根据XML字符串 建立JDom的Document对象
    *
    * @param xmlString XML格式的字符串
    * @return Document 返回建立的JDom的Document对象,建立不成功将抛出异常。
    * @throws IOException
    * @throws JDOMException
    */
   private static Document getDocument(String xmlString) throws JDOMException, IOException {
//       SAXBuilder builder = new SAXBuilder();
//       Document anotherDocument =  builder.build( new StringReader(xmlString));

//       try {
//        Document doc = (Document)DocumentHelper.parseText(xmlString);
//         return doc;
//
//       } catch (DocumentException e) {
//        e.printStackTrace();
//    }

       StringReader st = new StringReader(xmlString);
       InputSource is = new InputSource(st);
       Document doc = (new SAXBuilder()).build(is);
       return doc;
   }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1016214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

非常详细的git-flow分支管理流程配置及使用

非常详细的git-flow分支管理流程配置及使用。 git-flow有两个涵义,一个是指软件开发领域的版本管理流程Gitflow。另一个是指git命令工具git flow。 目前业界主流的版本管理流程是Gitflow 和 trunk-based。 Gitflow流行的比较早。但是目前的流行度要低于 trunk-based模式工作…

Linux系统:OpenSSH7.4p升级到9.0p(服务器漏洞)

清华大学开源软件镜像站下载地址&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/pub/OpenBSD/OpenSSH/portable/openssh-9.0p1.tar.gz 一、升级 0、安装Telnet &#xff08;1&#xff09;为防止安装失败&#xff0c;无法用ssh做远程连接&#xff0c;因此先安装telnet yum…

elasticsearch3-索引库的操作

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…

视屏点播项目

项目背景 大家应该在电脑上刷过视频吧,这个项目就是模拟一下我们刷视频的整个流程,我们要做的是一个类似B站的网页,这里面包含视频的上传修改和观看以及删除,注意我这个是一个简易版本的,在后面我会做一个升级,增加其他的功能. 基本原理 下面我们说一下我们项目的基本原理.我…

RabbitMQ快速实战以及集群架构详解

一、 MQ 介绍 1 、什么是 MQ &#xff1f;为什么要用 MQ &#xff1f; ChatGPT 中对于消息队列的介绍是这样的&#xff1a; MQ &#xff1a; MessageQueue &#xff0c;消息队列。这东西分两个部分来理解&#xff1a;队列&#xff0c;是一种 FIFO 先进先出的数据结构。 消…

社区团购商城小程序v18.1开源独立版+前端

新增后台清理缓存功能 修复定位权限 修复无法删除手机端管理员 11月新登录接口修复&#xff01; 修复商家付款到零钱&#xff0c; 修复会员登陆不显示头像&#xff0c; 修复无法修改会员开添加绑定

elasticsearch10-查询文档处理

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…

C++核心编程之类和对象---C++面向对象的三大特性--封装

目录 类和对象 类和对象的概念 C面向对象的三大特性 一、封装 封装案例1&#xff1a;设计一个学生类&#xff0c;可以给姓名和学号赋值&#xff0c;可以显示学生的姓名和学号。 二、访问权限 访问权限有三种 struct和class的区别 三、成员属性私有化 成员属性私有化的…

第十三章总结

一.泛型 1.定义泛型类 泛型机制语法&#xff1a; 类名<T> 其中&#xff0c;T是泛型的名称&#xff0c;代表某一种类型。 【例13.6】创建带泛型的图书类 代码&#xff1a; 结果&#xff1a; 2.泛型的常规用法 (1)定义泛型类时声明多个变量 class MyCla…

【MySQL集群一】CentOS 7上搭建MySQL集群:一主一从、多主多从

CentOS 7上搭建MySQL集群 介绍一主一从步骤1&#xff1a;准备工作步骤2&#xff1a;安装MySQL步骤3&#xff1a;配置主服务器步骤4&#xff1a;创建复制用户步骤5&#xff1a;备份主服务器数据&#xff0c;如果没有数据则省略这一步步骤6&#xff1a;配置从服务器步骤7&#xf…

Javase | 集合-上

目录&#xff1a; 一、集合&#xff1a;1.集合的概述2.集合的分类 二、“单个方式”存储元素&#xff1a;1.Collection1.1 Collection的概述1.2 Collection接口中常用的方法Iterator<T> iterator( ) 1.3 Collection下的子接口 2.Iterable&#xff1a;2.1 Iterable的概述2…

国内AI语言大模型【星火】各类模块及部分功能使用方法介绍

一、前言 现在AI语言大模型是百花齐放,挺好!有竞争,有发展,才能推出更好的产品。现在,科大讯飞就推出了大语言模型——星火!能够学习和理解人类的语言,进行多轮对话,回答问题,高效便捷地帮助人们获取信息、知识和灵感。星火在对话栏设置了三个插件:文档回答、PPT生成…

Java中transient关键字的详细总结

Java中transient关键字的详细总结 概要介绍 本文要介绍的是Java中的transient关键字&#xff0c;transient是短暂的意思。对于transient 修饰的成员变量&#xff0c;在类的实例对象的序列化处理过程中会被忽略。 因此&#xff0c;transient变量不会贯穿对象的序列化和反序列化…

C2基础设施威胁情报对抗策略

威胁情报是指在信息安全和安全防御领域&#xff0c;收集、分析和解释与潜在威胁相关的信息&#xff0c;以便预先发现并评估可能对组织资产造成损害的潜在威胁&#xff0c;是一种多维度、综合性的方法&#xff0c;其通过信息的收集、分析和研判&#xff0c;帮助组织了解可能对其…

Linux学习第11天:字符设备驱动开发:一字一符总见情

本文是驱动开发的第一篇笔记。主要内容是字符设备驱动开发最基础的内容&#xff0c;主要包括字符设备的概念、开发步骤以及一个十分重要的概念&#xff1a;设备号。其思维导图能简单的显示本文的基本框架&#xff0c;如下&#xff1a; 一、字符设备 字符设备就是一个一个字节&a…

MySQL注入绕安全狗脚本 -- MySQLByPassForSafeDog,以及端口爆破工具 -- PortBrute配置使用

工具介绍 此Tamper仅仅适用于MySQL数据库&#xff0c;在SQLMap使用过程中添加参数–tamperMySQLByPassForSafeDog。 安装与使用 1、安装网站安全狗Apache最新版 2、启用安全狗&#xff0c;不加MySQLByPassForSafeDog绕狗Tamper: python sqlmap.py -u "http://192.168.…

又一个Python调试利器

迷途小书童 读完需要 5分钟 速读仅需 2 分钟 1 简介 在编程过程中&#xff0c;几乎难以避免的会出现错误。事实上&#xff0c;程序员为了消除错误&#xff0c;要花费大量的时间在代码调试上。在调试过程中&#xff0c;使用 print() 语句来理解程序流程和发现意外行为无疑是最常…

iOS系统暗黑模式

系统暗黑模式&#xff1a; 暗黑模式颜色适配&#xff1a; 方式1&#xff1a; Assets配置&#xff1a;在Assets中配置好颜色后&#xff0c;可以通过colorNamed: 放大获取到动态颜色。 方式2&#xff1a;代码配置&#xff0c;通过代码colorWithDynamicProvider: 可以看出来生成…

C语言指针进阶(2)

大家好&#xff0c;我们今天继续来分享指针进阶的内容。 目录 5.函数指针 6.函数指针数组 7. 指向函数指针数组的指针 8. 回调函数 5.函数指针 顾名思义函数指针里面存的就是函数的地址了。 那我们通过一段代码来理解函数指针&#xff1a; #include<stdio.h> int Add…

向日葵无法连接服务器(无法登录)

最近在使用向日葵过程中&#xff0c;突然就不能登录向日葵了&#xff0c;网上查了各种解决方案&#xff0c;比如说防火墙是不是把向日葵给拦截了&#xff1f;更换不同的版本等等&#xff0c;都无法解决&#xff0c;最后突然想到是不是电脑对向日葵原安装目录限制了&#xff1f;…