工作中可能会遇到一个项目要在不同的数据库环境中切换,我们利用MybatisPlus
可以实现大部分的功能,但是如果遇到特殊的自定义函数,比如时间函数,可能就得自己去实现了。有些人可能会想通过获取数据库方言,然后在Mapper.xml中将其作为参数传递过去,这种方式确实可以,但有两点问题:
- 需要获取
Datasource
的jdbc
然后判断方言(没有找到直接获取方言的api,应该有,找到的人麻烦告知下) - 最重要的一点,这种方式引入了非业务属性,很不符合我们的设计理念。
其实Mybatis
已经为我们解决了这个问题,通过DatabaseIdProvider
便可实现。他的使用方式很简单,只需要加上如下配置即可
/**
* 数据库方言配置
* @return
*/
@Bean
public DatabaseIdProvider databaseIdProvider() {
VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties properties = new Properties();
properties.put("Oracle","oracle");
properties.put("MySQL","mysql");
properties.setProperty("PostgreSQL", "postgresql");
properties.setProperty("DB2", "db2");
properties.setProperty("SQL Server", "sqlserver");
databaseIdProvider.setProperties(properties);
return databaseIdProvider;
}
添加位置看自己意愿,可以专门创建DatabaseConfig
配置类,也可以写到*Application
启动类下。
使用方式
<!--查询商品列表-->
<select id="queryList" databaseId="sqlserver">
select * from goods where DATEDIFF(d, create_time, #{date}) >= 0
</delete>
<!--查询商品列表-->
<select id="queryList" databaseId="mysql">
select * from goods where TO_DAYS(#{date}) >= TO_DAYS(create_time)
</delete>
或者
<!--查询商品列表-->
<select id="queryList">
<if test="_databaseId == 'mysql'">
select * from goods where TO_DAYS(#{date}) >= TO_DAYS(create_time)
</if>
<if test="_databaseId == 'sqlserver'">
select * from goods where DATEDIFF(d, create_time, #{date}) >= 0
</if>
</delete>
到此就可以了。
那么为什么直接配置DatabaseIdProvider
就可以了呢,他是配置在什么地方,又是在什么时候被加载的呢?
其实DatabaseIdProvider
是被配置到了SqlSessionFactoryBean
,我们知道SqlSessionFactoryBean
的创建是在MybatisAutoConfiguration
中,当然我们也可以自己创建。下面看MybatisAutoConfiguration
的源码
public MybatisAutoConfiguration(...
ObjectProvider<DatabaseIdProvider> databaseIdProvider,
...) {
...
this.databaseIdProvider = databaseIdProvider.getIfAvailable();
...
}
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
...
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
...
return factory.getObject();
}
为了看着方便,我省略了不是本次要说明的部分代码,可以看到databaseIdProvider
是在其构造方法中传入的,并且在sqlSessionFactory
方法中被配置到SqlSessionFactoryBean
中的。
那么如果用的是MybatisPlus
要怎么样配置呢,很简单和Mybatis
是一样的。请看MybatisPlusAutoConfiguration
源码,你会发现对databaseIdProvider
的处理是一样的。