修改了mybatis的xml中的sql不重启服务器如何动态加载更新

07-21 1214阅读

目录

一、背景

修改了mybatis的xml中的sql不重启服务器如何动态加载更新

二、注意

三、代码

四、使用示例

五、其他参考博客


一、背景

开发一个报表功能,好几百行sql,每次修改完想自测下都要重启服务器,启动一次服务器就要3分钟,重启10次就要半小时,耗不起时间呀。于是在网上找半天,没发现能直接用的, 最后还是乖乖用了自己的业余时间,参考了网上内容写了个合适自己的类。

二、注意

1.本类在mybatis-plus-boot-starter 3.4.0, mybatis3.5.5下有效,其他版本没试过

2.部分idea版本修改了xml中的sql后,并不会直接写入到硬盘中,而是保留在内存中,需要手动ctrl+s或者切换到其他窗口才能触发写入新内容到硬盘,所以使用本类时要确认你修改的sql确实已经保存进硬盘里了

3.xml所在文件夹的绝对位置,需要你修改下,再使用本类

 

三、代码

用一个类就能实现开发阶段sql热更新

这个类可以配置启动一个线程,每10秒重新加载最近有修改过的sql

也可以调用一下接口重新修改过的sql

代码如下:

package com.gree;
import com.baomidou.mybatisplus.core.MybatisMapperRegistry;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.builder.xml.XMLMapperEntityResolver;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
/**
 * 本类用于热部署mybatis xml中修改的sql
 * 注意:
 *  1.本类在mybatis-plus-boot-starter 3.4.0 和 mybatis3.5.5 下有效,其他版本没试过
 *  2.部分idea版本修改了xml中的sql后,并不会直接写入到硬盘中,而是保留在内存中,需要手动ctrl+s或者切换到其他窗口才能触发写入新内容到硬盘,所以使用本类时要确认你修改的sql确实已经保存进硬盘里了
 *  3.xml所在文件夹的绝对位置,需要你修改下,再使用本类
 */
@RestController
public class MybatisMapperRefresh {
    //xml所在文件夹的绝对位置(这里改成你的位置)
    private String mapperPath = "D:\\wjh\\Mome\\openGitCode\\mybatisRefreshDemo\\src\\main\\resources\\mapper";
    //是否需要启动一个线程,每隔一段时间就刷新下
    private boolean needStartThread = false;
    //刷新间隔时间(秒)
    private int sleepSeconds = 10;

    //项目启动时间(或加载本class的时间)
    private long startTime = new Date().getTime();
    //上次执行更新xml的时间
    private long lasteUpdateTime = 0;
    private static final Log logger = LogFactory.getLog(MybatisMapperRefresh.class);
    private SqlSessionFactory sqlSessionFactory;
    private Configuration configuration;
    /**
     * 构造函数,由spring调用生成bean
     * @param sqlSessionFactory
     */
    public MybatisMapperRefresh(
            SqlSessionFactory sqlSessionFactory
    ) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.configuration = sqlSessionFactory.getConfiguration();
        if (needStartThread) {
            this.startThread();
        }
    }
    /**
     * 调用这个接口刷新你的sql,接口会返回刷新了哪些xml
     * @return
     */
    @RequestMapping("/sql/refresh")
    public List refreshMapper() {
        List refreshedList = new ArrayList();
        try {
            refreshedList = refreshDir();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return refreshedList;
    }
    /**
     * 启动一个线程,每间隔一段时间就更新下xml中的sql
     */
    public void startThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    logger.warn("线程循环中!");
                    try {
                        refreshDir();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        Thread.sleep(sleepSeconds * 1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "mybatis-plus MapperRefresh").start();
    }
    /**
     * 刷新指定目录下所有xml文件
     *
     * @throws Exception
     */
    private List refreshDir() throws Exception {
        List refreshedList = new ArrayList();
        try {
            //获取指定目录下,修改时间大于上次刷新时间,并且修改时间大于项目启动时间的xml
            List fileList = FileUtil.getAllFiles(mapperPath);
            ArrayList needUpdateFiles = new ArrayList();
            for (File file : fileList) {
                long lastModified = file.lastModified();
                if (file.isFile() && startTime 
    

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]