日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/11/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mybatis动态更新xml文件后热部署,不重启应用的方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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文件后热部署,不重启应用的方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。