Generate database tables according to mybatis/ibatis sqlmapper file parsing

There is a complete source code of the application, but the table structure is missing. If I slowly create one by one according to the DO objects, it is also a headache. One is because there are dozens of tables, and the other is copy and paste this thing. There is no technical content at all, which is really not what I want to do. Originally, I wanted to search for such a tool on the Internet. I used a lot of keywords. I have tried both Chinese and English, such as "How to create a table structure according to SqlMap", "How to generate table from sqlmap", etc., or I can't find it. After all, there are a few who have object source code but no table structure like me, so I plan to do it myself.
    Fortunately, I am familiar with the application itself. I know what kind of database is used, what is the naming style of the files, etc. It should not be an experience to generate a table structure based on objects. The way I thought at first was to generate it based on the DO object. Later, I looked at the mapping between the MYSQL field type and the JAVA object found. I found that there are many one-to-many situations. I felt that this was unreliable, so I gave up this solution. ; Later, I found that there is a mapping between objects and fields in the SQLMPA configuration file. This is easy. It is OK to analyze this file directly, so I have the following codes:

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; 
 
/**
* Regenerate the table structure according to the SqlMap configuration file of Ibatis. <br>
* All corresponding fields in sqlmap are required to have the attribute jdbcType.

* @author Administrator 2012-7-2 09:33:07 PM
*/ 
public class Sqlmap2Table { 
 
    // All varchars are 512 by default, which is guaranteed to satisfy most fields 
    private static final String DEFAULT_VARCHAR_LENGTH = "VARCHAR(256 )"; 
 
    public static void main(String[] args) throws JDOMException, IOException { 
        String sqlMapPath = "I:/Site/proc/xxx_trunk/dal/src/conf";//Specify the path where your sqlmap configuration file is located for 
        analysis (sqlMapPath); 
    } 
 
    /**
     * Perform traversal analysis according to the specified directory
     * 
     * @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()); 
                } 
            } 
        } 
    } 
 
    /**
     * Analyze a single sqlmap configuration file
     * 
     * @param sqlMapFile
     * @throws IOException
     * @throws JDOMException
     */ 
    private static void analysisSqlMap(String sqlMapFile) throws IOException, JDOMException { 
        // System.out.println("****** ******"+sqlMapFile); 
         boolean isNull=false;
        /**
         * This line in the sqlmap file should be removed here: <br>
         * <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"><br>
         * Otherwise, when JDom creates a Document object based on the file, it will report that www.ibatis cannot be found .com is an exception, resulting in unsuccessful rendering.
         */ 
        String xmlString = filterRead(sqlMapFile, "<!DOCTYPE"); 
        Document doc = getDocument(xmlString); 
        List<Element> resultMap = (List<Element>) XPath.selectNodes(doc, "//resultMap"); 
        for (Element e : resultMap) { 
            String alias = e.getAttributeValue("type"); 
            String tableName = getTableName(doc, alias); 
            List<Element> children = e.getChildren(); 
            StringBuilder createTableString = new StringBuilder("create table " + tableName + "(\n\t"); 
            int size = 0; 
            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"; 
                }
                
                createTableString.append(child.getAttributeValue("column")).append(" ").append(jdbcType); 
                if (size < children.size() - 1) { 
                    createTableString.append(",\n\t"); 
 
                } else { 
                    createTableString.append("\n"); 
                } 
                size++; 
            } 
            if(isNull){
            break;
            }
            createTableString.append(");"); 
            System.out.println(createTableString.toString().toUpperCase()); 
        } 
    } 
 
    private static String getTableName(Document doc, String alias) throws JDOMException { 
        String tableName = ""; 
        String classPath = null; 
        // The alias here may be an alias, or it may be a java class path, here I pass the alias is it a bit The symbol "." is used to distinguish 
        if (alias.indexOf(".") > 0) {// is a JAVA class 
            classPath = alias; 
        } else {// is an alias, go to the configured alias to find 
            Element aliasElement = ( Element) XPath.selectSingleNode(doc, "//typeAlias[@alias=\"" + alias + "\"]"); 
            classPath = aliasElement.getAttributeValue("type"); 
        } 
        String[] classPathArray = classPath.split( "\\."); 
        // Get the name of DO 
        classPath = classPathArray[classPathArray.length - 1]; 
        int i = classPath.lastIndexOf("DO"); 
        // Get the DO name generated from the table name, without the two characters "DO" 
        classPath = classPath.substring(0, i); 
        char[] chars = classPath.toCharArray (); 
        boolean isFirst = Boolean.TRUE; 
        // generate real table name 
        for (char c : chars) { 
            if (!isFirst && c >= 65 && c <= 90) { 
                tableName += "_"; 
            } 
            if (isFirst) { 
                isFirst = Boolean.FALSE; 
            } 
            tableName += c; 
        } 
        // Convert table name to uppercase and return 
        return tableName.toUpperCase(); 
    } 
 
    /**
     * Filtered reading
     * 
     * @param filePath file path
     * @param notIncludeLineStartWith Characters not included, that is, the beginning of a line is such a string, the line will be ignored when reading
     * @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; 
    } 
 
    /**
     * according to XML string Create JDom's Document object
     * 
     * @param xmlString XML format string
     * @return Document Returns the created JDom's Document object, if the creation is unsuccessful, an exception will be thrown.
     * @throws IOException
     * @throws JDOMException
     */ 
    private static Document getDocument(String xmlString) throws JDOMException, IOException { 
 
        SAXBuilder builder = new SAXBuilder(); 
        Document anotherDocument = builder.build(new StringReader(xmlString)); 
        return anotherDocument; 
 
    } 


    JDOM dependencies are required here.
    However, there are a few points to note:
    1. The relationship between primary keys and foreign keys is not reflected here. There is no way. Only manual additions are made here.
    2. In each sqlmap file, the result field in each resultMap must have the line jdbcType , otherwise it will report a null pointer exception that the attribute cannot be found. Of course, here you can create a mapping relationship between javaType and jdbcType, and find jdbcType according to javaType
    . To be removed, otherwise an error will be reported when the object is generated.
    Almost there, I ran successfully.

The code is in the attachment, please download and view.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326880061&siteId=291194637