`

根据mybatis/ibatis sqlmapper文件解析生成数据库表

    博客分类:
  • JAVA
 
阅读更多
有一份应用完整的源码,不过就是缺少了表结构,如果让我根据DO对象一个个去慢慢创建,也是个让人头痛的问题,一是因为有几十个表,二是这个东西拷贝粘贴一点技术含量都没有,这真不是我愿意干的活。本来是想在网上搜索一份这样的工具,关键字到是用了一大堆,中文英文都试过了,如“如何根据SqlMap创建表结构”、"How to generate table from sqlmap"等,还是木有找到,毕竟有几个是像我这样有对象源码却木有表结构的,于是就打算自己搞定了。
    幸好我对这份应用本身还是比较熟悉,知道用的是什么样的数据库,文件的命名风格是怎么样的等,想来根据对象生成表结构应该不是什么验事。刚开始想的方式是根据DO对象来生成,后来根据找到的MYSQL字段类型与JAVA对象的映射一看,发现一对多的情况有不少,觉得这种不靠谱,于是就放弃这种方案;后面发现SQLMPA配置文件中有对象与字段的映射,这个倒是省事了,直接分析这个文件就OK了,于是乎就有了下面这些代码:

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; 
 
/**
* 根据Ibatis的SqlMap配置文件,重新生成表结构。<br>
* 要求所有的sqlmap中对应的字段都有jdbcType这个属性。

* @author Administrator 2012-7-2 下午09:33:07
*/ 
public class Sqlmap2Table { 
 
    // 默认所有的varchar都是512,可以保证满足绝大多数的字段 
    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";//这里指定你的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配置文件
     * 
     * @param sqlMapFile
     * @throws IOException
     * @throws JDOMException
     */ 
    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"); 
        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; 
        // 这里的alias可能是一个别名,也可能是一个java类路径,这里我通过该alias是否有点"."这个符号来区别 
        if (alias.indexOf(".") > 0) {// 是JAVA类 
            classPath = alias; 
        } else {// 是别名,就到配置的别名中去找 
            Element aliasElement = (Element) XPath.selectSingleNode(doc, "//typeAlias[@alias=\"" + alias + "\"]"); 
            classPath = aliasElement.getAttributeValue("type"); 
        } 
        String[] classPathArray = classPath.split("\\."); 
        // 取到DO的名称 
        classPath = classPathArray[classPathArray.length - 1]; 
        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)); 
        return anotherDocument; 
 
    } 


    这里需要JDOM的依赖。
    不过需要注意几点:
    1、这里体现不出主键、外键关系,没办法,这里只有手工补充了;
    2、每个sqlmap的文件中,每个resultMap中的result字段,都必须有jdbcType这一行,否则会报找不到属性的空指针异常,当然这里可以搞一个javaType与jdbcType的映射关系,根据javaType去找jdbcType,我这里用不着,就没有弄了;
    3、sqlmap的DOCTYPE在读出来的时候要去掉,否则生成对象的时候会报错。
    差不多了,我是跑成功了。

代码在附件,请下载查看。
分享到:
评论

相关推荐

    java-ssm+vue旅游资源网站实现源码(项目源码-说明文档)

    旅游资源网站的主要使用者分为管理员和用户,实现功能包括管理员:首页、个人中心、用户管理、景点信息管理、购票信息管理、酒店信息管理、客房类型管理、客房信息管理、客房预订管理、交流论坛、系统管理,用户:首页、个人中心、购票信息管理、客房预订管理、我的收藏管理,前台首页;首页、景点信息、酒店信息、客房信息、交流论坛、红色文化、个人中心、后台管理、客服等功能。 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog

    【高创新】基于粒子群优化算法PSO-Transformer-BiLSTM实现故障识别Matlab实现.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    这里收集那些神奇的产品经理为我们带来的意想不到的产品功能和改版,又称_MDZZ_PM_awesome-pm.zip

    这里收集那些神奇的产品经理为我们带来的意想不到的产品功能和改版,又称_MDZZ_PM_awesome-pm

    AI City track 5数据集-voc-xml格式

    有戴头盔的人、未戴头盔的人、摩托车三种类别,包含736张图像、对应voc格式标签(xml)

    4-3_Business_BLUE_2017_16-CL-20180524MTAX.potx

    微软演示材料

    VB075期刊信息管理系统(SQL).7z

    VB075期刊信息管理系统(SQL).7z

    西门子SMART200程序 PID的控制写法,突破8路,PID直接做成子程序,无密码,直接调用

    西门子SMART200程序 PID的控制写法,突破8路,PID直接做成子程序,无密码,直接调用。

    VBATM校园自动银行系统设计(源代码+论文).zip

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、5资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。

    基于深度学习的移动物体检测分类源码

    基于YOLOv5的物体检测识别与分类系统,可根据不同的权重模型对不同的物体进行识别,整体分为图片、视频和摄像头三个检测模块,具体检测能力依据模型而定。

    PMSM滑模控制仿真无位置 永磁电机 可提供文档if启动 如果没有收敛,将1e-4搞小一点 e-6或者e-5试下 本次滑模模型

    PMSM滑模控制仿真无位置 永磁电机 可提供文档if启动 如果没有收敛,将1e-4搞小一点 e-6或者e-5试下 本次滑模模型文档包括: 1 simulink界面调整,由于使用这个仿真的时候很可能会出现因为软件环境不同导致无法使用, 或者导致的波形错误,特写了一个关于参数界面的设置,按照那个设置,结合主框图,能够 避免使用出问题。 2 波形记录,将转速波形,转矩波形,位置估计+实际位置波形,三项定子电流波形, 给定转速(蓝绿色)+实际转速(红色)+估算转速(蓝色) 3 另外仿真程序内部,里面标注了各个功能模块的位置及部分原理。 4 lunwen的话推荐看 13 16 开头的lunwen,其他的可以拓展性的看。

    60-AspNet8-jQery-Datatables-5-Code.zip

    构建使用jQuery组件DataTables.net的Asp.Net 8 MVC应用程序的实用指南。

    皮层微创脑机接口传感器的发展现状与未来趋势

    内容概要:文章探讨了皮层微创脑机接口(BCI)传感器作为神经电信号采集与调控装置,在临床上的应用现状与科研进展,并分析了传感器在未来可能的发展趋势和技术革新点。介绍了现有商业化及实验级别的电极器材,并讨论了其如何进一步向着高通量、软界面与更持久的生命设计演化。 适合人群:神经工程专业科研工作者,尤其是关注BCI传感器领域的研究生、教师和其他相关专业的科研人士。 使用场景及目标:旨在增进从业者对于皮层微创BCI的理解,特别是传感器的设计、制作工艺和未来可能的方向;有助于科研与产品研发。 其他说明:文章还强调了技术创新在材料与设计理念层面的重要性,为BCI传感器在实际医疗与神经科研中发挥作用打下了坚实的基础。

    基于python实现的社会力模型仿真+源码+文档(毕业设计&课程设计&项目开发)

    基于python实现的社会力模型仿真+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于python实现的社会力模型仿真+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于python实现的社会力模型仿真+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于python实现的社会力模型仿真+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于python实现的社会力模型仿真+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于python实现的社会力模型仿真+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~

    2024.9.18 作业

    2024.9.18 作业

    Python环境一键安装脚本,适用于Linux_lxspacepy.zip

    Python环境一键安装脚本,适用于Linux_lxspacepy

    昕一 - 一样的月光 [qmms2].mp3

    昕一 - 一样的月光 [qmms2].mp3

    【高创新】基于凌日优化算法TSOA-Transformer-BiLSTM实现故障识别Matlab实现.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    http服务器的实现.7z

    http服务器的实现.7z

    java-ssm+vue高校奖学金管理系统实现源码(项目源码-说明文档)

    高校奖学金管理系统的主要实现功能包括:管理员:首页、个人中心、学生管理、辅导员管理、教务处管理、奖学金类型管理、奖学金信息管理、学生成绩管理、奖惩信息管理、奖学金申请管理、公告信息管理。学生:首页、个人中心、奖学金信息管理、学生成绩管理、奖惩信息管理、奖学金申请管理、公告信息管理,辅导员;首页、个人中心、学生管理、学生成绩管理、奖惩信息管理、奖学金申请管理、公告信息管理,教务处;首页、个人中心、学生管理、学生成绩管理、奖惩信息管理、奖学金申请管理、公告信息管理 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog

    Palo Alto Networks PA-220 管理员指导手册

    Palo Alto Networks PA-220 管理员指导手册

Global site tag (gtag.js) - Google Analytics