1. 在全局配置文件中配置environments
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多类似的用例。
不过要记住:尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一。
所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单:
- 每个数据库对应一个 SqlSessionFactory 实例
<!-- 配置数据源 -->
<environments default="dev_mysql">
<environment id="dev_mysql">
<!-- 事务管理:采用的是JDBC的事务管理 -->
<transactionManager type="JDBC" />
<!-- 配置数据源连接池: POOLED使用的是Mybatis自己的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
<environment id="dev_db2">
<!-- 事务管理:采用的是JDBC的事务管理 -->
<transactionManager type="JDBC" />
<!-- 配置数据源连接池: POOLED使用的是Mybatis自己的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${db2.driver}" />
<property name="url" value="${db2.url}" />
<property name="username" value="${db2.username}" />
<property name="password" value="${db2.password}" />
</dataSource>
</environment>
</environments>
注意这里的关键点:
- 默认的环境 ID(比如:default=“development”)。
- 每个 environment 元素定义的环境 ID(比如:id=“development”)。
- 事务管理器的配置(比如:type=“JDBC”)。
- 数据源的配置(比如:type=“POOLED”)。
默认的环境和环境 ID 是自解释的,因此一目了然。你可以对环境随意命名,但一定要保证默认的环境 ID 要匹配其中一个环境 ID。
如要使用不同的数据源,只需要切换environments中的default属性为dev_mysql或dev_db2即可。
2. 配置DB Properties
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8
db.username=xxx
db.password=xxx
db2.driver=com.ibm.db2.jcc.DB2Driver
db2.url=jdbc:db2://localhost:50000/ssm
db2.username=xxx
db2.password=xxx
3. 在全局配置文件中配置databaseIdProvider
MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。 为支持多厂商特性只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 即可:
<databaseIdProvider type="DB_VENDOR" />
这里的 DB_VENDOR 会通过 DatabaseMetaData#getDatabaseProductName() 返回的字符串进行设置。 由于通常情况下这个字符串都非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短,如下:
<!-- 配置数据库厂商标识别名 -->
<databaseIdProvider type="DB_VENDOR">
<property name="MYSQL" value="mysql"/>
<property name="DB2" value="db2"/>
<property name="SQL Server" value="sqlserver"/>
<property name="Oracle" value="oracle" />
</databaseIdProvider>
4. 在映射文件中编写适合不同数据库的sql
这里需要强调一点的是,同一个映射文件中,如果select标签加上了databaseId属性,这时是可以存在多个id相同的select标签的,但必须要保证databaseId是不一样的。
另外,如果有一个id一样的select标签,但是没有databaseId属性,那么Mybatis加载的时候会精确定位到有databaseId属性的那一个标签,忽略掉没有databaseId属性的那个标签。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alfred.mybatis.mapper.TbHkHolidayMapper">
<select id="findHKHoliday" parameterType="int"
resultType="com.alfred.mybatis.po.HKHoliday" >
SELECT *
FROM TB_HK_HOLIDAY
WHERE HK_ID = #{id}
</select>
<select id="findHKHoliday" parameterType="int"
resultType="com.alfred.mybatis.po.HKHoliday" databaseId="mysql">
SELECT *
FROM TB_HK_HOLIDAY
WHERE HK_ID = #{id}
</select>
<select id="findHKHoliday" parameterType="int"
resultType="com.alfred.mybatis.po.HKHoliday" databaseId="db2">
SELECT *
FROM EQR.TB_HK_HOLIDAY
WHERE HK_ID = #{id}
</select>
</mapper>
5. 运行测试及结果记录
@Test
public void testFindHkHoliday() throws Exception {
// 构造UserMapper对象(sqlSession)
SqlSession sqlSession = sqlSessionFactory.openSession();
// 需要传的参数就是被代理的Mapper接口
TbHkHolidayMapper mapper = sqlSession.getMapper(TbHkHolidayMapper.class);
// 调用TbHkHolidayMapper 对象的findHKHoliday
HKHoliday day = mapper.findHKHoliday(1);
System.out.println(day);