当前位置: 首页 > news >正文

饰品网站建设徐州工作招聘信息网

饰品网站建设,徐州工作招聘信息网,东莞技术好的网站建设推广,搜索引擎网站盈利模式大家好#xff0c;我是烤鸭: 今天介绍一下springboot mybatis 热加载mapper.xml文件。 本来不打算写的#xff0c;看到网上比较流行的方式都比较麻烦#xff0c;想着简化一下。 网上流行的版本。 https://www.cnblogs.com/oskyhg/p/8587701.html 总结一下需要#xff1a;my…大家好我是烤鸭: 今天介绍一下springboot mybatis 热加载mapper.xml文件。 本来不打算写的看到网上比较流行的方式都比较麻烦想着简化一下。 网上流行的版本。 https://www.cnblogs.com/oskyhg/p/8587701.html 总结一下需要mybatis-configmybatis-refresh.propertiesMapperRefresh.javaSqlSessionFactoryBean.java 按照这个博客写的确实挺好用的。但是springboot简便就是简便在没有配置文件。 于是看看能不能优化一下。优化后只需要mybatis-refresh.propertiesMapperRefresh.java一行代码 环境 springboot     2.0.0.RELEASE     mybatis    3.4.4 mybatis-spring-boot-starter    1.3.0 1.    MapperRefresh.java(同上复制) 定时读取指定目录下的mapper.xml文件是否被修改 package com.xxx.web.common.config.mybatis;import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;import org.apache.commons.lang.StringUtils; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.session.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.NestedIOException; import org.springframework.core.io.Resource; import com.google.common.collect.Sets; /** * 刷新MyBatis Mapper XML 线程 * author ThinkGem * version 2016-5-29 */ public class MapperRefresh implements java.lang.Runnable { public static Logger log LoggerFactory.getLogger(MapperRefresh.class); private static String filename mybatis-refresh.properties; private static Properties prop new Properties(); private static boolean enabled; // 是否启用Mapper刷新线程功能 private static boolean refresh; // 刷新启用后是否启动了刷新线程 private SetString location; // Mapper实际资源路径 private Resource[] mapperLocations; // Mapper资源路径 private Configuration configuration; // MyBatis配置对象 private Long beforeTime 0L; // 上一次刷新时间 private static int delaySeconds; // 延迟刷新秒数 private static int sleepSeconds; // 休眠时间 private static String mappingPath; // xml文件夹匹配字符串需要根据需要修改 static { // try { // prop.load(MapperRefresh.class.getResourceAsStream(filename)); // } catch (Exception e) { // e.printStackTrace(); // System.out.println(Load mybatis-refresh “filename” file error.); // } URL url MapperRefresh.class.getClassLoader().getResource(filename);InputStream is;try {is url.openStream();if (is null) {log.warn(applicationConfig.properties not found.);} else {prop.load(is);} } catch (IOException e) {e.printStackTrace();}String value getPropString(enabled);System.out.println(value);enabled true.equalsIgnoreCase(value); delaySeconds getPropInt(delaySeconds); sleepSeconds getPropInt(sleepSeconds); mappingPath getPropString(mappingPath); delaySeconds delaySeconds 0 ? 50 : delaySeconds; sleepSeconds sleepSeconds 0 ? 3 : sleepSeconds; mappingPath StringUtils.isBlank(mappingPath) ? mappings : mappingPath; log.debug([enabled] enabled); log.debug([delaySeconds] delaySeconds); log.debug([sleepSeconds] sleepSeconds); log.debug([mappingPath] mappingPath); } public static boolean isRefresh() { return refresh; } public MapperRefresh(Resource[] mapperLocations, Configuration configuration) { this.mapperLocations mapperLocations; this.configuration configuration; } Override public void run() { beforeTime System.currentTimeMillis(); log.debug([location] location); log.debug([configuration] configuration); if (enabled) { // 启动刷新线程 final MapperRefresh runnable this; new Thread(new java.lang.Runnable() { Override public void run() { if (location null){ location Sets.newHashSet(); log.debug(MapperLocations length: mapperLocations.length); for (Resource mapperLocation : mapperLocations) { String s mapperLocation.toString().replaceAll(\\\\, /); s s.substring(file [.length(), s.lastIndexOf(mappingPath) mappingPath.length()); if (!location.contains(s)) { location.add(s); log.debug(Location: s); } } log.debug(Locarions size: location.size()); } try { Thread.sleep(delaySeconds * 1000); } catch (InterruptedException e2) { e2.printStackTrace(); } refresh true; System.out.println( Enabled refresh mybatis mapper ); while (true) { try { for (String s : location) { runnable.refresh(s, beforeTime); } } catch (Exception e1) { e1.printStackTrace(); } try { Thread.sleep(sleepSeconds * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }, MyBatis-Mapper-Refresh).start(); } } /** * 执行刷新 * param filePath 刷新目录 * param beforeTime 上次刷新时间 * throws NestedIOException 解析异常 * throws FileNotFoundException 文件未找到 * author ThinkGem */ SuppressWarnings({ rawtypes, unchecked }) private void refresh(String filePath, Long beforeTime) throws Exception { // 本次刷新时间 Long refrehTime System.currentTimeMillis(); // 获取需要刷新的Mapper文件列表 ListFile fileList this.getRefreshFile(new File(filePath), beforeTime); if (fileList.size() 0) { log.debug(Refresh file: fileList.size()); } for (int i 0; i fileList.size(); i) { InputStream inputStream new FileInputStream(fileList.get(i)); String resource fileList.get(i).getAbsolutePath(); try { // 清理原有资源更新为自己的StrictMap方便增量重新加载 String[] mapFieldNames new String[]{ mappedStatements, caches, resultMaps, parameterMaps, keyGenerators, sqlFragments }; for (String fieldName : mapFieldNames){ Field field configuration.getClass().getDeclaredField(fieldName); field.setAccessible(true); Map map ((Map)field.get(configuration)); if (!(map instanceof StrictMap)){ Map newMap new StrictMap(StringUtils.capitalize(fieldName) collection); for (Object key : map.keySet()){ try { newMap.put(key, map.get(key)); }catch(IllegalArgumentException ex){ newMap.put(key, ex.getMessage()); } } field.set(configuration, newMap); } } // 清理已加载的资源标识方便让它重新加载。 Field loadedResourcesField configuration.getClass().getDeclaredField(loadedResources); loadedResourcesField.setAccessible(true); Set loadedResourcesSet ((Set)loadedResourcesField.get(configuration)); loadedResourcesSet.remove(resource); //重新编译加载资源文件。 XMLMapperBuilder xmlMapperBuilder new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); xmlMapperBuilder.parse(); } catch (Exception e) { throw new NestedIOException(Failed to parse mapping resource: resource , e); } finally { ErrorContext.instance().reset(); } // System.out.println(Refresh file: mappingPath StringUtils.substringAfterLast(fileList.get(i).getAbsolutePath(), mappingPath)); if (log.isDebugEnabled()) { log.debug(Refresh file: fileList.get(i).getAbsolutePath()); log.debug(Refresh filename: fileList.get(i).getName()); } } // 如果刷新了文件则修改刷新时间否则不修改 if (fileList.size() 0) { this.beforeTime refrehTime; } } /** * 获取需要刷新的文件列表 * param dir 目录 * param beforeTime 上次刷新时间 * return 刷新文件列表 */ private ListFile getRefreshFile(File dir, Long beforeTime) { ListFile fileList new ArrayListFile(); File[] files dir.listFiles(); if (files ! null) { for (int i 0; i files.length; i) { File file files[i]; if (file.isDirectory()) { fileList.addAll(this.getRefreshFile(file, beforeTime)); } else if (file.isFile()) { if (this.checkFile(file, beforeTime)) { fileList.add(file); } } else { System.out.println(Error file. file.getName()); } } } return fileList; } /** * 判断文件是否需要刷新 * param file 文件 * param beforeTime 上次刷新时间 * return 需要刷新返回true否则返回false */ private boolean checkFile(File file, Long beforeTime) { if (file.lastModified() beforeTime) { return true; } return false; } /** * 获取整数属性 * param key * return */ private static int getPropInt(String key) { int i 0; try { i Integer.parseInt(getPropString(key)); } catch (Exception e) { } return i; } /** * 获取字符串属性 * param key * return */ private static String getPropString(String key) { return prop null ? null : prop.getProperty(key).trim(); } /** * 重写 org.apache.ibatis.session.Configuration.StrictMap 类 * 来自 MyBatis3.4.0版本修改 put 方法允许反复 put更新。 */ public static class StrictMapV extends HashMapString, V { private static final long serialVersionUID -4950446264854982944L; private String name; public StrictMap(String name, int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); this.name name; } public StrictMap(String name, int initialCapacity) { super(initialCapacity); this.name name; } public StrictMap(String name) { super(); this.name name; } public StrictMap(String name, MapString, ? extends V m) { super(m); this.name name; } SuppressWarnings(unchecked) public V put(String key, V value) { // ThinkGem 如果现在状态为刷新则刷新(先删除后添加) if (MapperRefresh.isRefresh()) { remove(key); // MapperRefresh.log.debug(refresh key: key.substring(key.lastIndexOf(.) 1)); } // ThinkGem end if (containsKey(key)) { throw new IllegalArgumentException(name already contains value for key); } if (key.contains(.)) { final String shortKey getShortName(key); if (super.get(shortKey) null) { super.put(shortKey, value); } else { super.put(shortKey, (V) new Ambiguity(shortKey)); } } return super.put(key, value); } public V get(Object key) { V value super.get(key); if (value null) { throw new IllegalArgumentException(name does not contain value for key); } if (value instanceof Ambiguity) { throw new IllegalArgumentException(((Ambiguity) value).getSubject() is ambiguous in name (try using the full name including the namespace, or rename one of the entries)); } return value; } private String getShortName(String key) { final String[] keyparts key.split(\\.); return keyparts[keyparts.length - 1]; } protected static class Ambiguity { private String subject; public Ambiguity(String subject) { this.subject subject; } public String getSubject() { return subject; } } } }2.    mybatis-refresh.properties(同上复制) 设置读取配置文件的参数定时和频率是否多线程 enabledtrue delaySeconds30 sleepSeconds10 mappingPathmybatis 3.     关于sqlSessionFactory 网上大多的实现方式都是重新创建SqlSessionFactory然后再注入。 类似这样 我的疑问 1.    MapperRefresh需要当前sqlSessionBean的configuration。既然springboot都已经sqlSessionFactory把创建好了直接获取sqlSessionBean的configuration不就好了么。 2.    yml配置mybatis的时候没有sqlMapConfig(myabtis-config).xml这个配置文件还得先创建一个很不方便。试着把配置文件那行注释掉会报错Location 不能为空。 4.    改进 只需要在mybatis的sqlSessionFactory创建完成注入SqlSession调用MapperRefresh启动。 RootConfiguration.java package com.xxx.web.common.config;import java.io.IOException; import java.util.concurrent.Executors;import javax.annotation.PostConstruct;import org.apache.ibatis.session.SqlSession; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.stereotype.Controller;import com.xxx.web.common.config.mybatis.MapperRefresh;Configuration ComponentScan(value com.xxx, excludeFilters { Filter(Controller.class),Filter(type FilterType.ASSIGNABLE_TYPE, value { RootConfiguration.class }) }) MapperScan({com.xxx.web.**.dao}) public class RootConfiguration extends SpringBootServletInitializer {Autowiredprivate SqlSession sqlSession;Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {application.registerShutdownHook(false);return application.sources(RootConfiguration.class);}PostConstructpublic void postConstruct() throws IOException {//Constant.threadPool Executors.newFixedThreadPool(20);Resource[] resources new PathMatchingResourcePatternResolver().getResources(classpath*:mybatis/**/*Mapper.xml);new MapperRefresh(resources, sqlSession.getConfiguration()).run();} } 启动类 MainApplication.java package com.xxx.web;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;import com.xxx.web.common.config.RootConfiguration;SpringBootApplication public class MainApplication {public static void main(String[] args) {SpringApplication.run(RootConfiguration.class, args);} }application.yml spring: thymeleaf:prefix: classpath:/templates/datasource: type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/xxx?allowMultiQueriestrueuseUnicodetruecharacterEncodingutf-8username: adminpassword: admin2017initialSize: 1minIdle: 3maxActive: 20# 配置获取连接等待超时的时间maxWait: 60000# 配置间隔多久才进行一次检测检测需要关闭的空闲连接单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间单位是毫秒minEvictableIdleTimeMillis: 50000validationQuery: select xtestWhileIdle: truetestOnBorrow: falsetestOnReturn: false# 打开PSCache并且指定每个连接上PSCache的大小poolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20# 配置监控统计拦截的filters去掉后监控界面sql无法统计wall用于防火墙 #,wallfilters: stat,slf4j# 通过connectProperties属性来打开mergeSql功能慢SQL记录connectionProperties: druid.stat.mergeSqltrue;druid.stat.slowSqlMillis5000# 合并多个DruidDataSource的监控数据useGlobalDataSourceStat: true mybatis: configuration:map-underscore-to-camel-case: true#打印日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: mybatis/**/*Mapper.xmltypeAliasesPackage: com.xxx.entity.* #配置缓存和session存储方式默认ehcache,可选redis cacheType: ehcache 5.    多说一句 关于mybatis-refresh.properties中mappingPath 指的是src/main/resources的最父级的mybatis文件夹按下图的话 mappingPathmybatis
http://www.zqtcl.cn/news/304190/

相关文章:

  • 做外贸站推广全国网页制作大赛
  • 手机网站关键词排名微信小程序怎么做网页
  • 利用万网做网站wordpress过滤敏感
  • 大连 响应式网站制作郑州网站建设中国建设建设银行
  • 网站关键词布局关于静态网站开发相关新闻
  • 安徽新站优化网站建设哪些好
  • 网站详细页制作c2c模式的网站
  • 网站与网页之间的区别是什么意思通过微信发布诱导分享的美文或者集赞活动属于哪种网络营销方式
  • 可信网站代码想学做网站从哪里入手
  • 做公众号选择图片的网站wordpress怎么看代码
  • 个人 中小企业公司网站建设方案百度网页版链接地址
  • 青岛网站推广方案网线制作心得与体会
  • 杭州网站优化公司哈尔滨企业网站模板建站
  • 洛阳免费网站建设自己做网站最新视频教程
  • 网站备案查询 美橙网开发app需要的技术
  • 软件产品如何做网站推广昆山外贸网站建设推广
  • 景德镇市城市建设规划网站wordpress用不了了
  • 网站及新媒体建设宣传片wordpress 无法编辑主题
  • 东莞设计网站重庆做腋臭骑士网站
  • 什么软件可以搜索关键词精准网站信息优化的方式
  • 购物网站排名前十名山东泰安建筑工程集团有限公司
  • 源码下载站用vs网站开发
  • 自己做网站seo彩票的网站怎么做
  • 如何在网站后台找到死链接网站内页权重查询
  • 专业做国际网站网站开发的编程软件
  • 如何运营垂直网站网页工具大全
  • 如何让自己做的网站可以播放歌曲做培训网站
  • 做网站的毕业设计网站没备案怎么做淘宝客
  • 百度申诉网站建设银行住房租赁代表品牌是什么
  • 网站初期推广方案虚拟服务器搭建wordpress