使用databaseIdProvider标签实现多数据库支持
当应用需要支持不同数据库产商
,并且依赖了不同数据库特有的函数或者语法时,我们通常需要书写2套或以上是SQL来支持不同的场景。
场景
- 获取数据库时间:Oracle使用
sysdate
,而MySQL使用now()
- 获取列表:Oracle 12c后使用
listagg()
,而MySQL使用group_concat()
- 其他场景…
一些可能的方案
假设没有<databaseIdProvider/>
标签的情况下,我们可以如何实现我们的需求?我们用获取列表的场景来展示:
- 使用不同的
statemetnId
区分不用数据库的SQL,缺点是API会十分臃肿
。
- AccountMapper.xml
<!-- oracle use listagg -->
<select id="listAccountWithOracle" resultType="hashmap">
select owner, listagg(name, ',') as accounts from account group by owner
</select>
<!-- mysql use group_concat -->
<select id="listAccountWithMySQL" resultType="hashmap">
select owner, group_concat(name) as accounts from account group by owner
</select>
- AccountMapper.java
public interface AccountMapper {
/**
* support oracle listagg function
*
* @return list of owner and its accounts
*/
List<Map<String, Object>> listAccountWithOracle();
/**
* support mysql group_concat function
*
* @return list of owner and its accounts
*/
List<Map<String, Object>> listAccountWithMySQL();
}
- 定义
2套mapper.xml
来区分,保持API简洁,缺点是需要手动转换以加载不同的mapper文件,而且通用的语句也需要复制一份到不同的mapper文件中
。
- AccountMySQLMapper.xml
<!-- 省略其他的statement -->
<select