在最近的项目中,用到了MyIbatis3的动态加载映射文件的XML功能。在运行时动态添加SqlMapper映射文件。在网上没有查到相关资料,所以就自己研究了一下MyIbatis的Spring组件中的org.mybatis.spring.SqlSessionFactoryBean,研究其生成SqlSessionFactory过程,在buildSqlSessionFactory方法的末尾找到了加载映射文件的过程,代码如下:

if (!isEmpty(this.mapperLocations)) {
      for (Resource mapperLocation : this.mapperLocations) {
        if (mapperLocation == null) {
          continue;
        }

        try {
          XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
              configuration, mapperLocation.toString(), configuration.getSqlFragments());
          xmlMapperBuilder.parse();
        } catch (Exception e) {
          throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
        } finally {
          ErrorContext.instance().reset();
        }

        if (this.logger.isDebugEnabled()) {
          this.logger.debug("Parsed mapper file: '" + mapperLocation + "'");
        }
      }
    } else {
      if (this.logger.isDebugEnabled()) {
        this.logger.debug("Property 'mapperLocations' was not specified or no matching resources found");
      }
    }

    return this.sqlSessionFactoryBuilder.build(configuration);

可以看出主要加载的是configuration,只要获得了configuration,就可以动态加载了,SqlSessionFactory对象可以通过ApplicationContext上下文获得。
通过文件加载XML示例代码如下:

public static void loadXml(File file, SqlSessionFactory sqlSessionFactory) {
  Configuration configuration = sqlSessionFactory.getConfiguration();
  if (file.exists()) {
   try {
    new XMLMapperBuilder(new FileInputStream(file), configuration,
      file.toURI().toString(),
      configuration.getSqlFragments()).parse();
   } catch (Throwable e) {

   }
  }
 }

如果如Spring接口,就可以使用Spring的Resource对象来实现多次载入,可在Bean中配置的对象实现ApplicationContextAware接口,获取ApplicationContext对象的引用,从而使用通配符来加载多个XML文件,示例代码如下:

public static void loadXml(String locations,
   SqlSessionFactory sqlSessionFactory,
   ApplicationContext applicationContext) {
  if (locations == null)
   return;
  String[] mapperLocations = locations.split(",");
  Configuration configuration = sqlSessionFactory.getConfiguration();
  for (String location : mapperLocations) {
   try {
    Resource[] resources = applicationContext
      .getResources(location);
    if (resources != null) {
     for (Resource resource : resources) {
      new XMLMapperBuilder(resource.getInputStream(),
        configuration, resource.toString(),
        configuration.getSqlFragments()).parse();
     }
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

posted on 2012-06-18 17:08  黑衣魔术师  阅读(2551)  评论(0编辑  收藏  举报