mybatis mapper.xml转建表语句

从网上下载了代码,但是发现没有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>
java 复制代码
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;
   }

}
相关推荐
Dcs15 分钟前
VSCode等多款主流 IDE 爆出安全漏洞!插件“伪装认证”可执行恶意命令!
java
保持学习ing21 分钟前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
京东云开发者32 分钟前
Java的SPI机制详解
java
超级小忍1 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
程序无bug1 小时前
Spring IoC注解式开发无敌详细(细节丰富)
java·后端
小莫分享1 小时前
Java Lombok 入门
java
程序无bug1 小时前
Spring 对于事务上的应用的详细说明
java·后端
食亨技术团队1 小时前
被忽略的 SAAS 生命线:操作日志有多重要
java·后端
苦学编程的谢1 小时前
Maven
java·maven·intellij-idea
考虑考虑1 小时前
Maven 依赖范围(Scope)
java·后端·maven