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

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;
 
/**
 
  * <p>
  * </p>
 
  * @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<String, String> fileMapping =  new  HashMap<String, String>();
     private  Scanner scanner =  null ;
     private  ScheduledExecutorService service =  null ;
     private  Resource[] resources =  null ;
     private  File[] mapperFiles;
     private  Collection<Class<?>> 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<Class<?>> 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<Class<?>> 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();
         }
     }
 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值