你知道mybatis如何读取配置文件吗?

本文探讨了MyBatis如何读取配置文件,通常认为只有一种加载方式,但实际上是通过Resources类进行IO操作。Resources提供了五种资源加载方式,包括生成stream、properties、Reader、File和URL。以getResourceAsStream为例,详细介绍了加载过程,其余方法类似。了解这一过程有助于深化对MyBatis的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mybatis源码学习
用了这么久mybatis,你知道mybatis是如何读取配置文件的?

经常看到采用如下方式读取配置文件:

InputStream is = Resources.getResourceAsStream("mybatis-config.xml");

好像这成了唯一的加载方式,事实是这样的吗?


话不多说,直接源码

既然是读取文件/资源,那肯定牵涉到io操作。在mybatis源码中我们看到有个io包,路径为:org.apache.ibatis.io,然后我们看下其架构

在这里插入图片描述

由图中可以看出,类Resources聚合并创建`ClassLoaderWrapper对象。

Resources对资源的加载有五种方式,分别为:

  • 生成stream,getResourceAsStream
  • 生成properties,getResourceAsProperties
  • 生成Reader,getResourceAsReader
  • 生成File,getResourceAsFile
  • 生成URL,getResourceURL

上述每种方法都会有对应的重载方法,并调用ClassLoaderWrapper中对应的方法,主要是使用对应的类加载器(没有提供时采用默认)

以Resources#getResourceAsStream方法为例:

public class Resources {
  
  private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();//传入资源文件名称
  public static InputStream getResourceAsStream(String resource) throws IOException {
    //传入null 类加载,并调用其重载方法
    return getResourceAsStream(null, resource);
  }

  //getResourceAsStream 重载方法实际上调用classLoaderWrapper对象中对应的方法
  public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
    //具体调用
    InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);
    if (in == null) {
      throw new IOException("Could not find resource " + resource);
    }
    return in;
  }}
public class ClassLoaderWrapper {
  …
  ClassLoader defaultClassLoader;//默认类加载器
  ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();//系统类加载器
  
  public InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
    return getResourceAsStream(resource, getClassLoaders(classLoader));
  }
  
  InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
    //循环遍历各个类加载器,并使用非空的类加载器
    for (ClassLoader cl : classLoader) {
      if (null != cl) {
        // 试着根据资源名称生成输入流
        InputStream returnValue = cl.getResourceAsStream(resource);
        // 如果returnValue为null,可能是某些类加载器希望已[/]开头,所以会重新尝试加载
        if (null == returnValue) {
          returnValue = cl.getResourceAsStream("/" + resource);
        }
        //如果返回值不为null,则返回(否则继续遍历,直至遍历结束)
        if (null != returnValue) {
          return returnValue;
        }
      }
    }
    return null;
  }
  
  //创建类加载器组(同时也定义了类加载器的顺序)
  ClassLoader[] getClassLoaders(ClassLoader classLoader) {
    return new ClassLoader[]{
        classLoader,//传入的类加载器
        defaultClassLoader,//默认类加载器
        Thread.currentThread().getContextClassLoader(),//线程上下文类加载器
        getClass().getClassLoader(),//当前类加载器
        systemClassLoader//系统类加载器
    };
  }}

以上就是加载资源的过程,其他几种加载方式流程基本相同,不再赘述,有兴趣的朋友可以自行学习。


​ 微观世界,达观人生。

​ 做一名踏实的coder !

<think>嗯,用户想了解MyBatis如何通过读取映射文件来获取配置信息的原理和方法。首先,我需要回忆一下MyBatis的基本架构和工作流程。MyBatis的核心配置包括SqlSessionFactoryBuilder、SqlSessionFactory和SqlSession。配置信息通常存储在XML文件中,比如mybatis-config.xml和Mapper.xml。 用户提到的问题涉及到映射文件如何获取配置中的属性值,比如application.properties中的属性。我记得在Spring Boot项目中,可以通过在application.properties里设置属性,然后在MyBatis的配置中引用这些属性。例如,数据库连接信息可能会被动态注入到数据源配置中。 接下来,我需要考虑MyBatis如何解析这些配置文件。当应用启动时,SqlSessionFactoryBuilder会读取配置文件mybatis-config.xml,这个文件可能引用了多个Mapper.xml文件。每个Mapper.xml中的SQL语句可能会使用占位符,比如${db.run.username},来引用外部属性。这些属性可能来自外部的.properties文件,或者在Spring Boot环境中通过@Value注解注入。 另外,用户提供的引用[1]提到在Mapper.xml中使用变量并赋值为db.run.username的属性值。这应该涉及到MyBatis的属性替换机制,即在配置文件中定义变量,然后在映射文件中使用这些变量。可能需要结合Spring的Environment来动态获取属性值,特别是在Spring Boot整合的情况下。 还需要注意路径的问题,比如引用[2]提到的文件路径前加上“file:///”,这可能是为了正确加载外部配置文件。在整合Spring Boot时,通常会将MyBatis的配置参数放在application.properties中,然后通过配置类来创建SqlSessionFactory,这样MyBatis就能自动读取这些配置。 最后,用户可能需要具体的步骤和代码示例来说明如何实现动态属性的读取。例如,在mybatis-config.xml中定义<properties>标签,或者在Spring Boot的配置类中使用@ConfigurationProperties来绑定属性。此外,在Mapper.xml中使用${propertyName}的语法来引用这些属性值。 总结一下,MyBatis通过解析主配置文件和映射文件,结合外部属性源(如application.properties),利用属性替换机制动态获取配置信息。在Spring Boot环境中,这种整合更为自动化,通过配置类和环境变量简化了配置过程。</think>### MyBatis 读取映射文件获取配置信息的原理及方法 #### 一、配置信息读取的核心流程 1. **配置文件层级结构** MyBatis 通过主配置文件(如 `mybatis-config.xml`)定义全局参数(数据源、事务管理器等),并通过 `<mappers>` 标签关联映射文件(`Mapper.xml`)。例如: ```xml <!-- mybatis-config.xml --> <configuration> <properties resource="application.properties"/> <environments default="development"> <environment id="development"> <dataSource type="POOLED"> <property name="username" value="${db.run.username}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/UserMapper.xml"/> </mappers> </configuration> ``` 这里通过 `${db.run.username}` 动态引用 `application.properties` 中的属性[^1]。 2. **属性替换机制** MyBatis 使用 `org.apache.ibatis.parsing.PropertyParser` 解析配置文件中的占位符(如 `${key}`),优先从 `<properties>` 标签加载的属性或外部文件(如 `application.properties`)中取值。 --- #### 二、映射文件动态配置实现 在 `Mapper.xml` 中可直接引用全局配置中的属性,例如: ```xml <!-- UserMapper.xml --> <select id="getUser" resultType="User"> SELECT * FROM ${table.name} WHERE id = #{id} </select> ``` 此处 `${table.name}` 的值需在 `application.properties` 中定义: ```properties # application.properties db.run.username=admin table.name=user_table ``` --- #### 三、Spring Boot 整合的优化方法 1. **自动配置简化** Spring Boot 通过 `mybatis-spring-boot-starter` 自动加载 MyBatis 配置,无需手动指定 `mybatis-config.xml`。直接在 `application.yml` 中配置参数: ```yaml # application.yml mybatis: mapper-locations: classpath:mapper/*.xml configuration-properties: db.run.username: ${spring.datasource.username} ``` 2. **动态注入示例** 在配置类中通过 `@Value` 注入属性并传递给 MyBatis: ```java @Configuration public class MyBatisConfig { @Value("${db.run.username}") private String username; @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); Properties props = new Properties(); props.setProperty("db.run.username", username); factory.setConfigurationProperties(props); return factory.getObject(); } } ``` --- #### 四、关键注意事项 1. **路径格式** 外部配置文件需使用 `file:///` 前缀指定绝对路径(如 `file:///etc/config/application.properties`)[^2]。 2. **命名空间匹配** Mapper.xml 的 `namespace` 必须与接口完全一致,否则无法绑定映射关系[^3]: ```xml <mapper namespace="com.example.UserMapper"> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值