文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么使用mybatis-xmlreload实现修改xml文件再也不用重启项目

2023-07-05 17:06

关注

今天小编给大家分享一下怎么使用mybatis-xmlreload实现修改xml文件再也不用重启项目的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

ps:mybatis-xmlreload-spring-boot-starter目前 3.0.3.m1 版本实现了 xml 文件修改已有内容,比如修改 sql 语句、添加查询字段、添加查询条件等,可以实现热加载功能。但是对于 xml 文件添加 insert|update|delete|select 标签等内容后,是无法实现热加载的。众所周知,在 Idea 环境进行 Java 开发,在方法内修改方法内容是可以热加载的。但是添加新方法、添加方法参数,修改方法参数,修改方法返回值等都是无法直接热加载的。

一、mybatis-xmlreload-spring-boot-starter使用

mybatis-xmlreload-spring-boot-starter原理:

二、技术原理

mybatis-xmlreload-spring-boot-starter代码结构如下:

怎么使用mybatis-xmlreload实现修改xml文件再也不用重启项目

核心代码在MybatisXmlReload类中,执行逻辑:

        private MybatisXmlReloadProperties prop;        private List<SqlSessionFactory> sqlSessionFactories;    public MybatisXmlReload(MybatisXmlReloadProperties prop,             List<SqlSessionFactory> sqlSessionFactories) {        this.prop = prop;        this.sqlSessionFactories = sqlSessionFactories;    }
    // 解析项目所有xml路径,获取xml文件在target目录中的位置    List<Resource> mapperLocationsTmp = Stream.of(Optional.of(prop.getMapperLocations())    .orElse(new String[0]))    .flatMap(location -> Stream.of(getResources(patternResolver, location)))    .toList();
    // 根据xml文件在target目录下的位置,进行路径替换找到该xml文件在resources目录下的位置    for (Resource mapperLocation : mapperLocationsTmp) {        mapperLocations.add(mapperLocation);        String absolutePath = mapperLocation.getFile().getAbsolutePath();        File tmpFile = new File(absolutePath.replace(CLASS_PATH_TARGET, MAVEN_RESOURCES));        if (tmpFile.exists()) {            locationPatternSet.add(Path.of(tmpFile.getParent()));            FileSystemResource fileSystemResource = new FileSystemResource(tmpFile);            mapperLocations.add(fileSystemResource);        }    }
    // 对resources目录的xml文件修改进行监听    List<Path> rootPaths = new ArrayList<>();    rootPaths.addAll(locationPatternSet);    DirectoryWatcher watcher = DirectoryWatcher.builder()            .paths(rootPaths) // or use paths(directoriesToWatch)            .listener(event -> {                switch (event.eventType()) {                    case CREATE:                         break;                    case MODIFY:                         Path modifyPath = event.path();                        String absolutePath = modifyPath.toFile().getAbsolutePath();                        logger.info("mybatis xml file has changed:" + modifyPath);                        // 执行热加载逻辑...                        break;                    case DELETE:                         break;                }            })            .build();    ThreadFactory threadFactory = r -> {        Thread thread = new Thread(r);        thread.setName("xml-reload");        thread.setDaemon(true);        return thread;    };    watcher.watchAsync(new ScheduledThreadPoolExecutor(1, threadFactory));
  // 对多个数据源进行遍历,判断修改过的xml文件属于那个数据源  for (SqlSessionFactory sqlSessionFactory : sqlSessionFactories) {      ...  }
    // 根据 Configuration 对象获取对应的标签属性    Configuration targetConfiguration = sqlSessionFactory.getConfiguration();    Class<?> tClass = targetConfiguration.getClass(), aClass = targetConfiguration.getClass();    if (targetConfiguration.getClass().getSimpleName().equals("MybatisConfiguration")) {        aClass = Configuration.class;    }    Set<String> loadedResources = (Set<String>) getFieldValue(        targetConfiguration, aClass, "loadedResources");    loadedResources.clear();    Map<String, ResultMap> resultMaps = (Map<String, ResultMap>) getFieldValue(        targetConfiguration, tClass, "resultMaps");    Map<String, XNode> sqlFragmentsMaps = (Map<String, XNode>) getFieldValue(        targetConfiguration, tClass, "sqlFragments");    Map<String, MappedStatement> mappedStatementMaps =         (Map<String, MappedStatement>) getFieldValue(            targetConfiguration, tClass, "mappedStatements");
    // 遍历 resources 目录下 xml 文件列表    for (Resource mapperLocation : mapperLocations) {        ...    }
    // 判断是否是被修改过的xml文件,否则跳过    if (!absolutePath.equals(mapperLocation.getFile().getAbsolutePath())) {        continue;    }
    // 重新解析xml文件,替换Configuration对象的相对应属性    XPathParser parser = new XPathParser(mapperLocation.getInputStream(), true,         targetConfiguration.getVariables(),         new XMLMapperEntityResolver());    XNode mapperXnode = parser.evalNode("/mapper");    String namespace = mapperXnode.getStringAttribute("namespace");    List<XNode> resultMapNodes = mapperXnode.evalNodes("/mapper/resultMap");    for (XNode xNode : resultMapNodes) {        String id = xNode.getStringAttribute("id", xNode.getValueBasedIdentifier());        resultMaps.remove(namespace + "." + id);    }    List<XNode> sqlNodes = mapperXnode.evalNodes("/mapper/sql");    for (XNode sqlNode : sqlNodes) {        String id = sqlNode.getStringAttribute("id", sqlNode.getValueBasedIdentifier());        sqlFragmentsMaps.remove(namespace + "." + id);    }    List<XNode> msNodes = mapperXnode.evalNodes("select|insert|update|delete");    for (XNode msNode : msNodes) {        String id = msNode.getStringAttribute("id", msNode.getValueBasedIdentifier());        mappedStatementMaps.remove(namespace + "." + id);    }
    // 9. 重新加载和解析被修改的 xml 文件    try {        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(            mapperLocation.getInputStream(),            targetConfiguration,            mapperLocation.toString(),             targetConfiguration.getSqlFragments());        xmlMapperBuilder.parse();    } catch (Exception e) {        logger.error(e.getMessage(), e);    }

三、安装方式

<dependency>    <groupId>com.wayn</groupId>    <artifactId>mybatis-xmlreload-spring-boot-starter</artifactId>    <version>3.0.3.m1</version></dependency>
<dependency>    <groupId>com.wayn</groupId>    <artifactId>mybatis-xmlreload-spring-boot-starter</artifactId>    <version>2.0.1.m1</version></dependency>

四、使用配置

mybatis-xmlreload-spring-boot-starter 目前只有两个配置属性。mybatis-xml-reload.enabled 默认是 false, 也就是不启用 xml 文件的热加载功能,想要开启的话通过在项目配置文件中设置 mybatis-xml-reload.enabled 为 true。还有一个配置属性是 mybatis-xml-reload.mapper-locations,执行热加载的 xml 文件路径,这个属性需要手动填写,跟项目中的 mybatis.mapper-locations 保持一直即可。具体配置如下:

# mybatis xml文件热加载配置mybatis-xml-reload:  # 是否开启 xml 热更新,true开启,false不开启,默认为false  enabled: true   # xml文件路径,可以填写多个,逗号分隔。  # eg: `classpath*:mapper*Mapper.xml,classpath*:other*Mapper.xml`  mapper-locations: classpath:mapper/*Mapper.xml

以上就是“怎么使用mybatis-xmlreload实现修改xml文件再也不用重启项目”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯