Mybatis sql语句改变后,自动加载(xml和注解方式)

为什么80%的码农都做不了架构师?>>>   hot3.png

这个是在@歇蹩虎子 (http://www.oschina.net/code/snippet_1018034_26472)提供的自动加载的基础上改进的;

主要是添加了注解方式的自动加载

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.ibatis.binding.MapperRegistry;
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.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
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;

/**
 * 
 * 

 * 

 *   * @author 吕兵峰 2014-2-19 上午11:56:47  * @version V1.0  * @modificationHistory 如有逻辑或功能性重大变更记录,请修改一下以下内容  * @modify by user: {修改人} 2014-2-19  * @modify by reason:{方法名}:{原因}  */ public class MyMapperLoader implements DisposableBean, InitializingBean, ApplicationContextAware { private Logger logger = Logger.getLogger(MyMapperLoader.class); private ConfigurableApplicationContext context = null; private HashMap fileMapping = new HashMap(); private Scanner scanner = null; private ScheduledExecutorService service = null; private Resource[] resources = null; private File[] mapperFiles; private Collection> mappers; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = (ConfigurableApplicationContext) applicationContext; } @Override public void afterPropertiesSet() throws Exception { try { service = Executors.newScheduledThreadPool(1); // 获取xml SqlSessionFactoryBean sessionFactoryBean = context .getBean(SqlSessionFactoryBean.class); Field field = sessionFactoryBean.getClass().getDeclaredField( "mapperLocations"); field.setAccessible(true); resources = (Resource[]) field.get(sessionFactoryBean); //获取mapper的class SqlSessionFactory factory = context .getBean(SqlSessionFactory.class); Configuration configuration = factory.getConfiguration(); mappers = configuration.getMapperRegistry().getMappers(); mapperFiles = new File[mappers.size()]; Iterator> iterator = mappers.iterator(); int i = 0; while (iterator.hasNext()) { Class class1 = (Class) iterator.next(); URL url = new URL(class1.getResource("") + class1.getSimpleName() + ".class"); mapperFiles[i++] = new File(url.getFile()); } // 触发文件监听事件 scanner = new Scanner(); scanner.scan(); service.scheduleAtFixedRate(new Task(), 5, 5, TimeUnit.SECONDS); } catch (Exception e1) { e1.printStackTrace(); } } class Task implements Runnable { @Override public void run() { try { if (scanner.isChanged()) { logger.debug("文件改变,重新加载."); System.out.println(""); scanner.reload(); logger.debug("加载完毕."); } } catch (Exception e) { e.printStackTrace(); } } } @SuppressWarnings({ "rawtypes" }) class Scanner { public void reload() throws Exception { SqlSessionFactory factory = context .getBean(SqlSessionFactory.class); Configuration configuration = factory.getConfiguration(); // 移除加载项 removeConfig(configuration); // 重新扫描加载xml if (resources != null) { for (int i = 0; i < resources.length; i++) { if (resources[i] == null) { continue; } try { XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder( resources[i].getInputStream(), configuration, resources[i].toString(), configuration.getSqlFragments()); xmlMapperBuilder.parse(); } catch (Exception e) { throw new NestedIOException( "Failed to parse mapping resource: '" + resources[i] + "'", e); } finally { ErrorContext.instance().reset(); } } } // 重新扫描加载class Field f = Configuration.class.getDeclaredField("mapperRegistry"); f.setAccessible(true); f.set(configuration, new MapperRegistry(configuration)); Iterator> iterator = mappers.iterator(); while (iterator.hasNext()) { Class class1 = (Class) iterator.next(); configuration.addMapper(class1); } } 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 mapConfig = (Map) field.get(configuration); mapConfig.clear(); } 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(); } public void scan() throws IOException { if (!fileMapping.isEmpty()) { return; } if (resources != null) { for (int i = 0; i < resources.length; i++) { String multi_key = getValue(resources[i]); fileMapping.put(resources[i].getFilename(), multi_key); } } if (mapperFiles != null) { for (int i = 0; i < mapperFiles.length; i++) { fileMapping.put(mapperFiles[i].getAbsolutePath(), mapperFiles[i].lastModified() + ""); } } } private String getValue(Resource resource) throws IOException { String contentLength = String.valueOf((resource.contentLength())); String lastModified = String.valueOf((resource.lastModified())); return new StringBuilder(contentLength).append(lastModified) .toString(); } public boolean isChanged() throws IOException { boolean isChanged = false; if (resources != null) { for (int i = 0; i < resources.length; i++) { String name = resources[i].getFilename(); String value = fileMapping.get(name); String multi_key = getValue(resources[i]); if (!multi_key.equals(value)) { isChanged = true; fileMapping.put(name, multi_key); } } } if (mapperFiles != null) { for (int i = 0; i < mapperFiles.length; i++) { String name = mapperFiles[i].getAbsolutePath(); String preValue = fileMapping.get(name); String curValue = mapperFiles[i].lastModified() + ""; if (!curValue.equals(preValue)) { isChanged = true; fileMapping.put(name, curValue); } } } return isChanged; } } @Override public void destroy() throws Exception { if (service != null) { service.shutdownNow(); } } }



转载于:https://my.oschina.net/lvice/blog/228444

你可能感兴趣的:(Mybatis sql语句改变后,自动加载(xml和注解方式))