在 Configuration源码详解章节中分析了mybatis解析properties的源码,通过源码可以发现properties支持3种用法。
1. property子元素
第一种就是通过properties下面的property子元素进行定义,也就是Configuration源码详解章节中的案例所示,
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--通过peroperties下面的property子元素定义-->
<properties>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/lzj?characterEncoding=utf8"/>
<property name="username" value="root"/>
</properties>
<!--数据库配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
</dataSource>
</environment>
</environments>
<!--mapper位置-->
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
2. properties文件
第二种方式就是把peroperty属性提取到一个专门管理属性的文件中,然后在mybatis的配置文件中直接引用这个属性文件。
如下所示,专门定义db.perperties属性文件,用来管理数据库的属性
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/lzj?characterEncoding=utf8
username=root
那么mybatis配置文件就可以简化成如下形式
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引用properties文件-->
<properties resource="db.perperties" />
<!--数据库配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
</dataSource>
</environment>
</environments>
<!--mapper位置-->
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
除了上面用resource指定引入的外部属性文件,可以用资源定位符或资源标识符来表示,如下所示:
<properties url="file:///E:/myfile/db.perperties" />
或者
<properties url="https:xxxxxx:xx/db.perperties" />
3. 程序代码方式传参
在创建SqlSessionFactory 对象时首先首先创建了XMLConfigBuilder类型的parser对象,该对象就是用来解析mybatis配置文件的。从build方法入参支持传入properties文件
SqlSessionFactoryBuilder
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//创建XMLConfigBuilder类型的parser对象
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
进入XMLConfigBuilder的构造函数,源码如下所示
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
}
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
super(new Configuration());
ErrorContext.instance().resource("SQL Mapper Configuration");
//把外面送进来的props文件设置到了configuration的variables变量中
this.configuration.setVariables(props);
this.parsed = false;
this.environment = environment;
this.parser = parser;
}
从上面源码可知,代码中送的properties文件最终被set到了configuration对象的variables变量中了。而从Configuration源码详解中解析properties属性的源码也可知,最终解析properties下的属性或者文件最终都会被set到configuration对象的variables对象中,所以说不管是配置式的,还是代码式的,殊途同归。