Mybatis 自动生成XML转换SQL工具

初衷

本人去git找源码时,发现部分代码,不提供sql文件。实在令人气愤。如果xml很多,一个一个去mysql 工具创建数据库,那也太可怕了。

思路

  1. 将mybatis创建的XML文件解析出来,只用到 resultMap 里面的数据。
  2. 根据mysql 创建数据表语句,将解析得到数据进行拼接。
  3. 将拼接好的数据,保存在一个.sql文件中

实践

使用 dom4j-2.1.3.jar 解析xml文件,fastjson-1.2.68.jar 格式化存放解析出来数据。

1、创建 ConvertTool 工具类,用于解析XML文件,数据拼接mysql语句。

public class ConvertTool {

    public static  List<JSONObject> start(String path) throws DocumentException {
        // 创建saxReader对象  
        SAXReader reader = new SAXReader();
        // 通过read方法读取一个文件 转换成Document对象  
        Document document = reader.read(new File(path));
        //获取根节点元素对象  
        Element node = document.getRootElement();
        List<JSONObject> jsonObject = new ArrayList<>();
        //读取dom4j.xml文件中所有元素
        listNodes(node,jsonObject);
        System.out.println(jsonObject.toString());
        return  jsonObject;

    }

    //节点内容
    public  static  void listNodes(Element node,  List<JSONObject> jsonObject) {
        String nodeName = node.getName();
        if ("result".equals(nodeName) || "id".equals(nodeName)
                || "resultMap".equals(nodeName) || "mapper".equals(nodeName)) {
            System.out.println("当前节点的名称::" + node.getName());
// 获取当前节点的所有属性节点  
            List<Attribute> list = node.attributes();
            JSONObject item = new JSONObject();
            // 遍历属性节点  
            for (Attribute attr : list) {
                System.out.println(attr.getText()
                        + "---" + attr.getName()
                        + "---" + attr.getValue());
                item.put(attr.getName(), attr.getValue());
            }
            if (item.get("namespace") == null) {
                jsonObject.add(item);
            }

//如果文本内容不是空,则打印
            if (!(node.getTextTrim().equals(""))) {
                System.out.println("文本内容::::" + node.getText());
            }
            // 当前节点下面子节点迭代器  
            Iterator<Element> it = node.elementIterator();

            // 遍历  
            while (it.hasNext()) {
// 获取某个子节点对象  
                Element e = it.next();
                // 对子节点进行遍历  
                listNodes(e,jsonObject);
            }
        } else {
            return;
        }

    }

    // 将xml解析出来的数据转换成String
    public  static  String handleXMLToText( List<List<JSONObject>> jsonData){
        StringBuffer stringBuffer =  new StringBuffer();
        String tableName = null; // 数据表名
        String typeVal = null;
        String column = null; // 列名
        String jdbcType = null; // 数据类型
        for(int i = 0; i  < jsonData.size(); i++){
            List<JSONObject> items = jsonData.get(i);
            stringBuffer.append("CREATE TABLE ");
            for (int j = 0; j  < items.size(); j++){
                JSONObject item = items.get(j);
                if (item.get("column") == null) {
                    typeVal = (String) item.get("type");
                    String[]  typeValS = typeVal.split("\\.");
                    tableName = typeValS[typeValS.length - 1];
                    System.out.println("数据表 名::::" + tableName);
                    stringBuffer.append(tableName + "( ");
                } else  {
                    column  = (String) item.get("column");
                    jdbcType  = (String) item.get("jdbcType");
                    stringBuffer.append(column + " " + jdbcType
                            + (("VARCHAR".equals(jdbcType))? "(255)" : "")
                            + (j == items.size() - 1 ? " " : "," + "\r\n"));
                }
            }
            stringBuffer.append("\r\n )\r\n");
        }
        System.out.println("数据sql::::" +  stringBuffer.toString());
        return  stringBuffer.toString();
    }

}

2、创建 FileTool工具类,用于读写数据。

public class FileTool {

    public static void  wirte(String path,String content){
        // 构建指定文件
        File file = new File(path);
        System.out.println("数据sql 路径::::" +  path);
        // 根据文件创建文件的输出流
        try (OutputStream os = new FileOutputStream(file)) {
            // 把内容转换成字节数组
            byte[] data = content.getBytes();
            // 向文件写入内容
            os.write(data);
        } catch (Exception e) {
            e.printStackTrace();

        }
    }


    public  static List<String> getXMLFiles(String path) {
        File file = new File(path);//File类型可以是文件也可以是文件夹
        File[] fileList = file.listFiles();//将该目录下的所有文件放置在一个File类型的数组中
        List<String> wjList = new ArrayList<String>();//新建一个文件集合
        for (int i = 0; i < fileList.length; i++) {
            if (fileList[i].isFile() && fileList[i].getName().endsWith(".xml") ) {//判断是否为XML文件
                wjList.add(fileList[i].getAbsolutePath());
            }
        }
        return  wjList;
    }
}

3、创建 JFrameMain SWING 可视化窗口类,用于操作以及一些逻辑判断

public class JFrameMain extends JFrame implements ActionListener{

    JButton open = null;
    Label pathLabel = null;
    TextField pathText = null;


    JButton openTarger = null;
    Label targerLabel = null;
    TextField targerText = null;


    JButton handleStart = null;
    public static void main(String[] args) {
        new JFrameMain();
    }
    public JFrameMain(){



        FlowLayout layout = new FlowLayout(FlowLayout.LEFT, 30, 20);
        Panel pannel = new Panel(layout);

        pathLabel = new Label();
        pathLabel.setText("选择XML文件目录:");

        pannel.add(pathLabel);

        open=new JButton("选择");
        open.setSize(80, 40);
        pannel.add(open);

        pathText = new TextField();
        pathText.setColumns(50);
        pathText.setEnabled(false);
        pannel.add(pathText);

        open.setActionCommand("path");
        open.addActionListener(this);


        targerLabel = new Label();
        targerLabel.setText("选择存放目录:");
        pannel.add(targerLabel);

        openTarger=new JButton("选择");
        openTarger.setSize(80, 40);
        pannel.add(openTarger);

        targerText = new TextField();
        targerText.setColumns(50);
        targerText.setEnabled(false);
        pannel.add(targerText);

        openTarger.setActionCommand("target");
        openTarger.addActionListener(this);

        handleStart = new JButton("开始");
        handleStart.setSize(750, 40);
        pannel.add(handleStart);
        handleStart.setActionCommand("start");
        handleStart.addActionListener(this);


        this.setBounds(400, 200, 700, 200);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(pannel);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("actionPerformed:"+ e.getActionCommand());
        // TODO Auto-generated method stub
        if ("path".equals(e.getActionCommand()) || "target".equals(e.getActionCommand())) {
            JFileChooser jfc=new JFileChooser();
            jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );
            jfc.showDialog(new JLabel(), "选择");
            File file=jfc.getSelectedFile();
            if(file.isDirectory()){
                System.out.println("文件夹:"+file.getAbsolutePath());
                if ("path".equals(e.getActionCommand())) {
                    pathText.setText(file.getAbsolutePath().toString());
                } else if ("target".equals(e.getActionCommand())){
                    targerText.setText(file.getAbsolutePath().toString());
                }
            }else{
                JOptionPane.showMessageDialog(null, "请选择文件夹");
                if ("path".equals(e.getActionCommand())) {
                    pathText.setText("");
                } else if ("target".equals(e.getActionCommand())){
                    pathText.setText("");
                }
                System.out.println("文件:"+file.getAbsolutePath());
            }
            System.out.println(jfc.getSelectedFile().getName());
        } else if ("start".equals(e.getActionCommand())) {
            String path = pathText.getText();
            String targetPath = targerText.getText();
            if ( ( path == null ||  "".equals(path))
                    ||  ( targetPath == null ||  "".equals(targetPath))
                    ) {
                JOptionPane.showMessageDialog(null, "请选择文件夹");
                return;
            }
            Long startTime =  new Date().getTime();
            System.out.println("开始转换"+  startTime);
            handleStart.setEnabled(false);
            handleFile();
            System.out.println("结束转换"+ new Date().getTime());
            System.out.println("转换消耗"+  (new Date().getTime() - startTime ));
            handleStart.setEnabled(true);
            JOptionPane.showMessageDialog(null, "转换成功转换消耗(ms)" + (new Date().getTime() - startTime ) );
        }

    }

    private  void  handleFile(){
        String path = pathText.getText();
        List<String> datas =  FileTool.getXMLFiles(path);
        System.out.println("xmls文件:"+ datas.toString());
        List<List<JSONObject>> jsonData = new ArrayList<>();
        for (int i = 0; i < datas.size(); i++){
            try {
                List<JSONObject> item =    ConvertTool.start(datas.get(i));
                jsonData.add(item);
            } catch (DocumentException e) {
                e.printStackTrace();
            }
        }
        System.out.println("xmls文件解析:"+ jsonData.toString());
        String result =  ConvertTool.handleXMLToText(jsonData);

        String targetPath = targerText.getText();
        targetPath += "\\"+ new Date().getTime()+ ".sql";
        FileTool.wirte(targetPath, result);

    }

}

运行 JFrameMain 即可。
页面:
202004221053.png
源码

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天也想MK代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值