首页 > 代码库 > Mybatis热加载Mapper.xml
Mybatis热加载Mapper.xml
开发的时候,写Mybatis Mapper.xml文件的时候,每次修改SQL都需要重启服务,感觉十分麻烦,于是尝试写了一个Mybatis的Mapper.xml热加载。
能在修改Mapper.xml之后重新加载Mybatis,开发的时候可以用一下。
Spring配置:
<bean id="MybatisMapperDynamicLoader" class="com.teststartup.MybatisMapperDynamicLoader" />
Java代码:
import java.io.IOException;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;import java.util.Set;import java.util.Timer;import java.util.TimerTask;import org.apache.ibatis.builder.xml.XMLMapperBuilder;import org.apache.ibatis.executor.ErrorContext;import org.apache.ibatis.session.Configuration;import org.apache.ibatis.session.SqlSessionFactory;import org.springframework.beans.BeansException;import org.springframework.beans.factory.InitializingBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.core.NestedIOException;import org.springframework.core.io.Resource;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.core.io.support.ResourcePatternResolver;public class MybatisMapperDynamicLoader implements InitializingBean, ApplicationContextAware { private final HashMap<String, String> mappers = new HashMap<String, String>(); private volatile ConfigurableApplicationContext context = null; private volatile Scanner scanner = null; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = (ConfigurableApplicationContext) applicationContext; } @Override public void afterPropertiesSet() throws Exception { try { scanner = new Scanner(); new Timer(true).schedule(new TimerTask() { public void run() { try { if (scanner.isChanged()) { System.out.println("load mapper.xml"); scanner.reloadXML(); } } catch (Exception e) { e.printStackTrace(); } } }, 10 * 1000, 5 * 1000); } catch (Exception e1) { e1.printStackTrace(); } } @SuppressWarnings("unchecked") class Scanner { private static final String XML_RESOURCE_PATTERN = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "**/*Sql.xml"; private final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); public Scanner() throws IOException { Resource[] resources = findResource(); if (resources != null) { for (Resource resource : resources) { String key = resource.getURI().toString(); String value = getMd(resource); mappers.put(key, value); } } } public void reloadXML() throws Exception { SqlSessionFactory factory = context.getBean(SqlSessionFactory.class); Configuration configuration = factory.getConfiguration(); removeConfig(configuration); for (Resource resource : findResource()) { try { XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(resource.getInputStream(), configuration, resource.toString(), configuration.getSqlFragments()); xmlMapperBuilder.parse(); } finally { ErrorContext.instance().reset(); } } } 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"); } private void clearMap(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception { Field field = classConfig.getDeclaredField(fieldName); field.setAccessible(true); ((Map) field.get(configuration)).clear(); } private void clearSet(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception { Field field = classConfig.getDeclaredField(fieldName); field.setAccessible(true); ((Set) field.get(configuration)).clear(); } public boolean isChanged() throws IOException { boolean isChanged = false; for (Resource resource : findResource()) { String key = resource.getURI().toString(); String value = getMd(resource); if (!value.equals(mappers.get(key))) { isChanged = true; mappers.put(key, value); } } return isChanged; } private Resource[] findResource() throws IOException { return resourcePatternResolver.getResources(XML_RESOURCE_PATTERN); } private String getMd(Resource resource) throws IOException { return new StringBuilder().append(resource.contentLength()).append("-").append(resource.lastModified()).toString(); } }}
Mybatis热加载Mapper.xml
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。