Springboot Mybatis Mybatis-Plus DatabaseIdProvider 根据不同数据库类型动态SQL实现

工作中可能会遇到一个项目要在不同的数据库环境中切换,我们利用MybatisPlus可以实现大部分的功能,但是如果遇到特殊的自定义函数,比如时间函数,可能就得自己去实现了。有些人可能会想通过获取数据库方言,然后在Mapper.xml中将其作为参数传递过去,这种方式确实可以,但有两点问题:

  1. 需要获取Datasourcejdbc然后判断方言(没有找到直接获取方言的api,应该有,找到的人麻烦告知下)
  2. 最重要的一点,这种方式引入了非业务属性,很不符合我们的设计理念。

其实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}) &gt;= 0
</delete>
<!--查询商品列表-->
<select id="queryList" databaseId="mysql">
  select * from goods where TO_DAYS(#{date}) &gt;= TO_DAYS(create_time)
</delete>

或者

<!--查询商品列表-->
<select id="queryList">
  <if test="_databaseId == 'mysql'">
  select * from goods where TO_DAYS(#{date}) &gt;= TO_DAYS(create_time)
  </if>
  <if test="_databaseId == 'sqlserver'">
  select * from goods where DATEDIFF(d, create_time, #{date}) &gt;= 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的处理是一样的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容