mybatis应用程序,由于是半自动化的sql, 有大量的sql是在xml文件中配置的,而在开发程序的过程中,通常需要边写sql变调试应用。但在默认情况下,xml文件里配置的sql语句是被放入到缓存中去了,每次更改有sql语句的xml文件,需要重新启动应用,这样工作效率很低,于是很希望有一个动态加载xml文件的功能,自动加载新的sql语句,并重新写入到缓存中,在网上参考了很多资料,最终弄了一个简单的东西出来,直接写成了spring mvc的controller。代码如下: 

package com.yihaomen.controller;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Scope("prototype")
@Controller
@RequestMapping("/sql")
public class SQLSessionCacheController {private Log log  = LogFactory.getLog(SQLSessionCacheController.class);@Autowiredprivate SqlSessionFactory sqlSessionFactory;private Resource[] mapperLocations;private String packageSearchPath = "classpath*:**/mappers/*.xml";private HashMap<String, Long> fileMapping = new HashMap<String, Long>();// 记录文件是否变化@RequestMapping("/refresh")@ResponseBodypublic String refreshMapper() {try {Configuration configuration = this.sqlSessionFactory.getConfiguration();// step.1 扫描文件try {this.scanMapperXml();} catch (IOException e) {log.error("packageSearchPath扫描包路径配置错误");return "packageSearchPath扫描包路径配置错误";}System.out.println("==============刷新前mapper中的内容===============");for (String name : configuration.getMappedStatementNames()) {System.out.println(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();log.info("mapper文件[" + configLocation.getFilename() + "]缓存加载成功");} catch (IOException e) {log.error("mapper文件[" + configLocation.getFilename() + "]不存在或内容格式不对");continue;}}}System.out.println("==============刷新后mapper中的内容===============");for (String name : configuration.getMappedStatementNames()) {System.out.println(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 = classConfig.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 = classConfig.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;}
}

注意事项: 
在我的应用中,mybatis配置文件放在这里的:classpath*:**/mappers/*.xml, 因此我定义死了,需要修改成自己的路径.

测试方法: 
可以通过controller提供的地址,直接在浏览器上输入url访问, 比如: http://localhost:8080/sql/refresh , 当然,你还可以通过js用ajax方式调用,都是可以的。

mybatis动态更新xml文件后热部署,不重启应用的方法相关推荐

  1. java jdom 更新xml_用JDOM完成Java更新XML文件

    用JDOM完成Java更新XML文件以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 本文详细介绍Java的文档对象模型 ...

  2. mybatis学习指南--xml文件方式篇

    mybatis学习指南---xml文件篇 以下内容是由我总结mybatis官方文档和实践中的一些经验,总共分为四篇:xml文件配置篇,java方式配置篇,缓存篇,其他配置篇,第一次这样正式的写一篇文章 ...

  3. Web开发如何实现Tomcat等服务器热部署不用重启

    Web开发如何实现Tomcat等服务器热部署不用重启 听语音 | 浏览:354 | 更新:2016-05-28 11:18 在进行java web开发的时候,对类改动一些代码后,通常就需要对服务器比如 ...

  4. 关于更新win11 22H2后透明任务栏失效的解决方法.2023.03.15

    关于更新win11 22H2后透明任务栏失效的解决方法2023.03.15 [ViVe Tool下载地址]{Releases · thebookisclosed/ViVe (github.com)} ...

  5. 读取xml文件转成ListT对象的两种方法(附源码)

    读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最近项目中用到的读取xml文件并且转成List<T>对象的方法, ...

  6. 还在手动部署jar包?太low了,动态上传jar包热部署真的爽!

    大家好,我是宝哥! 近期开发系统过程中遇到的一个需求,系统给定一个接口,用户可以自定义开发该接口的实现,并将实现打成jar包,上传到系统中.系统完成热部署,并切换该接口的实现. 定义简单的接口 这里以 ...

  7. Spring Boot整合MyBatis框架(XML文件版)

    1.创建数据库.数据库表并插入数据 创建数据库springboot: CREATE DATABASE springboot; 创建数据库表user: CREATE TABLE `user` (`id` ...

  8. mybatis的mapper.xml文件中含有中文注释时运行出错,mybatis配置优化和别名优化 mybatis配置之映射器说明

    记录一个发现的小问题,刚刚在UserMapper.xml文件中有一段中文注释掉的内容: <!-- <resultMap id="Usermap" type=" ...

  9. war包热更新_基于IDEA热部署更新服务器Tomcat类,服务器Tomcat热更新

    前言 在开发过程中,如果我们是使用的IDEA,就会知道IDEA有一个热更新的功能,何为热更新?就是在不重启Tomcat的情况下让服务器中的代码变更为最新的.这样既能快速的更新代码,又不用担心Tomca ...

最新文章

  1. void addColumn(TableColumn aColumn)
  2. 判断是否是电脑访问网站 1号店页面判断脚本
  3. 浙江工商大学计算机学院调剂录取,浙江工商大学2017年硕士研究生调剂拟录取名单公布(持续更新)...
  4. VTK:PolyData之RemoveOutsideSurface
  5. 金蝶k3财务接口_金蝶云为企业成长而生,让工作更高效!
  6. palm基础----8 国际化
  7. [转]微软代码示例:ASP.NET 2.0 三层架构应用程序教程系列
  8. 爬取人力资源社保局咨询问题
  9. 检查Python列表项是否在另一个字符串中包含一个字符串
  10. 解析几何 —— 椭圆
  11. 对‘pthread_create’未定义的引用_2018年度‘龙虎榜’统计分析(一)
  12. Hugging Face Course-Introduction学习小记 (part1)
  13. 凝胶渗透色谱法——聚合物相对分子质量分布的测定
  14. Swagger API文档Responses中Object类型无法显示,求指引
  15. idea spring boot 修改 html,js 等不用重启即时生效
  16. 海绵城市工程_海绵城市工程案例详解—雨水调蓄池
  17. css渐变小案例,比较复杂的线性渐变和径向渐变做泡泡
  18. 赠书 002丨文化改变脑,是玄学?
  19. 树莓派-从入手到使用(一):树莓派入手操作第一步
  20. docker compose搭建NACOS集群

热门文章

  1. lgg6可以root的版本_Kali Linux 2020.1版本变更内容
  2. python 示例_Python日历类| yeardayscalendar()方法与示例
  3. abap 添加alv上的工具栏的按钮_Excel里的置顶功能——快速访问工具栏
  4. read/fread write/fwrite 的区别
  5. 计算机编程要哪方面天赋,编程要哪门子天赋
  6. php实现视频转gif,在Linux上将视频转换成动态gif图片
  7. linux--几种常见的进程调度算法
  8. 【剑指offer】_11整数中1出现的次数
  9. 对象的浅拷贝和深拷贝
  10. gcc与g++编译器