MyBatis之databaseIdProvider多数据库支持
一、databaseIdProvider官方描述
MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。
这里什么意思呢 ,如果你仔细看过mybatis的官方文档中关于XML映射文件章节中的 select
<select
id="selectPerson"
parameterType="int"
parameterMap="deprecated"
resultType="hashmap"
resultMap="personResultMap"
flushCache="false"
useCache="true"
timeout="10000"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
1
2
3
4
5
6
7
8
9
10
11
12
下面的解释中有一个databaseId属性: 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。新增,修改和删除都有这个属性。例如mysql的获取系统时间函数 NOW() 和oracle的获取系统时间to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’) 是不同的。那么我们可以针对同一个修改可以写两个update语句,他们的databaseId属性不一样。
再比如数据库数据分页见MyBatis 入门(六)–分页查询(1)和MyBatis 入门(六)–分页查询(2) -插件方式他们的语句就是不一样,就可以利用这种模式获取当前数据,再做不同的处理。
为支持多厂商特性只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 即可:
配置
<databaseIdProvider type="DB_VENDOR" />
1
这里的 DB_VENDOR 会通过 DatabaseMetaData#getDatabaseProductName() 返回的字符串进行设置 见JDBC-基础。 由于通常情况下这个字符串都非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短,如下:
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle" />
</databaseIdProvider>
1
2
3
4
在有 properties 时,DB_VENDOR databaseIdProvider 的将被设置为第一个能匹配数据库产品名称的属性键对应的值,如果没有匹配的属性将会设置为 “null”。 在这个例子中,如果 getDatabaseProductName() 返回“Oracle (DataDirect)”,databaseId 将被设置为“oracle”。
你可以通过实现接口 org.apache.ibatis.mapping.DatabaseIdProvider 并在 mybatis-config.xml 中注册来构建自己的 DatabaseIdProvider:
public interface DatabaseIdProvider {
void setProperties(Properties p);
String getDatabaseId(DataSource dataSource) throws SQLException;
}
1
2
3
4
应用时可以直接通过Configuration的getDatabaseId方法来获取当前数据的供应商。
二、mysql和oracle两种数据库的应用实例
在这里我们就实现mysql的获取系统时间函数 NOW() 和oracle的获取系统时间to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’) 的的执行。
首先配置 mybatis-config.xml
<properties resource="jdbc.properties" />
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql" />
<property name="Oracle" value="oracle" />
</databaseIdProvider>
<mappers>
<mapper class="com.elements.user.dao.dbMapper" />
</mappers>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
接口和mapperXML文件
package com.elements.user.dao;
public interface dbMapper {
String SelectTime();
}
1
2
3
4
5
6
<?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.elements.user.dao.dbMapper" >
<select id="SelectTime" resultType="String" databaseId="mysql">
SELECT NOW() FROM dual
</select>
<select id="SelectTime" resultType="String" databaseId="oracle">
SELECT 'oralce'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM dual
</select>
</mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
上面的mapper文件具有相同的id,但是他们的databaseId分别是mysql和oralce。
jdbc.properties文件
#driver=com.mysql.cj.jdbc.Driver
#url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&useSSL=true&serverTimezone=UTC
#username=mybatis
#password=mybatis
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:mybatis
username=mybatis
password=mybatis
maxActive= 50
1
2
3
4
5
6
7
8
9
10
11
12
13
这个配置文件以及注销了mysql的链接,启用的是oralce的链接
测试类
package com.elements.user;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import com.elements.user.dao.dbMapper;
public class TestDB {
@Test
public void Testdb() throws IOException
{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
dbMapper user = (dbMapper) session
.getMapper(dbMapper.class);
System.out.println(user.SelectTime());
} finally {
session.close();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
结果说明
如果当前启用的是oracle则执行databaseId=”oracle”的语句,如果mysql值执行databaseId=”mysql”的语句
项目代码地址:http://pan.baidu.com/s/1o8rMc5s
---------------------
作者:火柴盒zhang
来源:CSDN
原文:https://blog.csdn.net/likewindy/article/details/51396576