侧边栏壁纸
  • 累计撰写 793 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论
标签搜索

目 录CONTENT

文章目录

自动刷新xml

Dettan
2021-04-10 / 0 评论 / 0 点赞 / 165 阅读 / 788 字
温馨提示:
本文最后更新于 2022-07-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
@RestController
@SpringBootApplication
public class RenrenApplication {
    @Autowired
    XMLMapperLoader xmlMapperLoader;

    public static void main(String[] args) {
        SpringApplication.run(RenrenApplication.class, args);
    }


    /**
     * 第一种方式,通过Spring的方式创建Bean来管理,在构造方法中会启动新的线程
     *
     * @return
     */
    @Bean
    public XMLMapperLoader xmlMapperLoader(SqlSessionFactory sqlSessionFactory) {
        return new XMLMapperLoader(sqlSessionFactory, "classpath:mapper/**/*.xml");
    }

    /**
     * 第二种方式 通过URL来刷新
     *
     * @return
     */
    @RequestMapping("refresh")
    public String refreshMyBatisXml() {
        return xmlMapperLoader.readMapperXml();
    }
}

package io.renren.common.utils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

/**
 * @author yuxuan
 */
public class XMLMapperLoader {

    private Logger logger = LoggerFactory.getLogger(XMLMapperLoader.class);
    private SqlSessionFactory sqlSessionFactory;
    private Resource[] mapperLocations;
    private String packageSearchPath = "classpath:mapper/**/*.xml";
    private HashMap<String, Long> fileMapping = new HashMap<String, Long>();

    public XMLMapperLoader(SqlSessionFactory sqlSessionFactory, String packageSearchPath) {
        this.sqlSessionFactory = sqlSessionFactory;
        if (packageSearchPath != null && packageSearchPath != "") {
            this.packageSearchPath = packageSearchPath;
        }
//        startThreadListener();
    }

    public void startThreadListener() {
        ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
        //每5秒执行一次
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                readMapperXml();
            }
        }, 0, 5, TimeUnit.SECONDS);
    }

    public String readMapperXml() {
        try {
            org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();
            // step.1 扫描文件
            try {
                this.scanMapperXml();
            } catch (IOException e) {
                return "packageSearchPath扫描包路径配置错误";
            }

            for (String name : configuration.getMappedStatementNames()) {
                logger.debug(name);
            }

            // step.2 判断是否有文件发生了变化
            if (this.isChanged()) {
                // step.2.1 清理
                this.removeConfig(configuration);
                // step.2.2 重新加载
                for (Resource configLocation : mapperLocations) {
                    try {
                        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configLocation.getInputStream(), configuration, configLocation.toString(), configuration.getSqlFragments());
                        xmlMapperBuilder.parse();
                        logger.debug("mapper文件[" + configLocation.getFilename() + "]缓存加载成功");
                    } catch (IOException e) {
                        logger.debug("mapper文件[" + configLocation.getFilename() + "]不存在或内容格式不对");
                        continue;
                    }
                }
            }

            for (String name : configuration.getMappedStatementNames()) {
                logger.debug(name);
            }
            return "刷新mybatis xml配置语句成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "刷新mybatis xml配置语句失败";
        }
    }


    public void setPackageSearchPath(String packageSearchPath) {
        this.packageSearchPath = packageSearchPath;
    }

    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    /**
     * 扫描xml文件所在的路径
     *
     * @throws IOException
     */
    private void scanMapperXml() throws IOException {
        this.mapperLocations = new PathMatchingResourcePatternResolver().getResources(packageSearchPath);
    }

    /**
     * 清空Configuration中几个重要的缓存
     *
     * @param configuration
     * @throws Exception
     */
    private void removeConfig(Configuration configuration) throws Exception {
        Class<?> classConfig = configuration.getClass();
        clearMap(classConfig, configuration, "mappedStatements");
        clearMap(classConfig, configuration, "caches");
        clearMap(classConfig, configuration, "resultMaps");
        clearMap(classConfig, configuration, "parameterMaps");
        clearMap(classConfig, configuration, "keyGenerators");
        clearMap(classConfig, configuration, "sqlFragments");

        clearSet(classConfig, configuration, "loadedResources");

    }

    @SuppressWarnings("rawtypes")
    private void clearMap(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {
        Field field = null;
        if (configuration.getClass().getName().equals("com.baomidou.mybatisplus.core.MybatisConfiguration")) {
            field = classConfig.getSuperclass().getDeclaredField(fieldName);
        } else {
            field = classConfig.getClass().getDeclaredField(fieldName);
        }
        field.setAccessible(true);
        Map mapConfig = (Map) field.get(configuration);
        mapConfig.clear();
    }

    @SuppressWarnings("rawtypes")
    private void clearSet(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {
        Field field = null;
        if (configuration.getClass().getName().equals("com.baomidou.mybatisplus.core.MybatisConfiguration")) {
            field = classConfig.getSuperclass().getDeclaredField(fieldName);
        } else {
            field = classConfig.getClass().getDeclaredField(fieldName);
        }
        field.setAccessible(true);
        Set setConfig = (Set) field.get(configuration);
        setConfig.clear();
    }

    /**
     * 判断文件是否发生了变化
     *
     * @param resource
     * @return
     * @throws IOException
     */
    private boolean isChanged() throws IOException {
        boolean flag = false;
        for (Resource resource : mapperLocations) {
            String resourceName = resource.getFilename();

            boolean addFlag = !fileMapping.containsKey(resourceName);// 此为新增标识

            // 修改文件:判断文件内容是否有变化
            Long compareFrame = fileMapping.get(resourceName);
            long lastFrame = resource.contentLength() + resource.lastModified();
            boolean modifyFlag = null != compareFrame && compareFrame.longValue() != lastFrame;// 此为修改标识

            // 新增或是修改时,存储文件
            if (addFlag || modifyFlag) {
                fileMapping.put(resourceName, Long.valueOf(lastFrame));// 文件内容帧值
                flag = true;
            }
        }
        return flag;
    }

}

5秒一刷新
或者访问 /baseUrl/refresh 手动刷新
0

评论区