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;
   }

}
相关推荐
.生产的驴2 分钟前
Electron Vue框架环境搭建 Vue3环境搭建
java·前端·vue.js·spring boot·后端·electron·ecmascript
爱学的小涛10 分钟前
【NIO基础】基于 NIO 中的组件实现对文件的操作(文件编程),FileChannel 详解
java·开发语言·笔记·后端·nio
吹老师个人app编程教学11 分钟前
详解Java中的BIO、NIO、AIO
java·开发语言·nio
爱学的小涛11 分钟前
【NIO基础】NIO(非阻塞 I/O)和 IO(传统 I/O)的区别,以及 NIO 的三大组件详解
java·开发语言·笔记·后端·nio
北极无雪15 分钟前
Spring源码学习:SpringMVC(4)DispatcherServlet请求入口分析
java·开发语言·后端·学习·spring
琴智冰19 分钟前
SpringBoot
java·数据库·spring boot
binqian19 分钟前
【SpringSecurity】基本流程
java·spring
猿小蔡-Cool1 小时前
CPU 多级缓存
java·spring·缓存
gopher95111 小时前
final,finally,finalize的区别
java·开发语言·jvm
Jason-河山1 小时前
利用 Python 爬虫采集 1688商品详情
java·http