背景
在对国产化数据有要求的时候,我们会做对 达梦、海量等数据库的配置。
有些SQL 以前没有写成标准SQL;
那么适配的时候怎么办呢?改成标准SQL。
如果不好改呢?比如SQL比较复杂等,需要判断 当前是哪个厂商的数据库,执行哪个厂商认识的SQL。
发现
发现mybatis已经支持 识别不同数据库厂商 mybatis文档
步骤一:配置dataBaseID
mybatis可以通过 databaseId识别数据库厂商,那么怎么配置呢?
方案一
使用mybatis的配置
mybatis:
configuration:
database-id: dm
方案二
声明 databaseIdProvider。给每个厂商重命名。
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @author: dong
* @date: 2024/6/15
* @Description:
*/
@Configuration
public class MyBatisConfig {
@Bean
public DatabaseIdProvider databaseIdProvider() {
VendorDatabaseIdProvider provider = new VendorDatabaseIdProvider();
Properties props = new Properties();
props.setProperty("Oracle", "oracle");
props.setProperty("MySQL", "mysql");
props.setProperty("PostgreSQL", "postgresql");
props.setProperty("DB2", "db2");
props.setProperty("SQL Server", "sqlserver");
props.setProperty("DM DBMS", "dm");
provider.setProperties(props);
return provider;
}
}
系统不能自己读吗?
如果不声明 databaseIdProvider,就不进行databaseId的配置了
步骤二:xml写不同数据库厂商的实现SQL
使用相同的id,不同的databaseId
不用区分的厂商:不用写databaseId
需要区分:databaseId=‘厂商简写’(方案二 DatabaseIdProvider 中配置的简写)
<!-- 对接Oracle的时候 -->
<select id="dmtest" databaseId="Oracle" resultType="map">
select 'oracle' from dual
</select>
<!-- 可以通用的时候 -->
<select id="dmtest" resultType="map">
select 'default' from dual
</select>
<!-- 对接达梦的时候 -->
<select id="dmtest" databaseId="dm" resultType="map">
select 'dm' from dual
</select>
直接使用databaseId判断
如果某个SQL语句,只有一个条件不能通用,可以使用if语句判断_databaseId 参数
<select id="dmtest" resultType="map">
<if test="_databaseId=='oracle'" >
select 'oracle1' from dual
</if>
<if test="_databaseId==null or _databaseId=='' " >
select 'default1' from dual
</if>
<if test="_databaseId=='dm'" >
select 'dm1' from dual
</if>
<if test="_databaseId=='d23'" >
select 'd231' from dual
</if>
</select>
源码
实现获取 不同厂商名字的源码,在文件 DatabaseIdProvider 中
每个数据库厂商,产品名字,在 DatabaseMetaData 类中,getDatabaseProductName 方法 中返回。
或者找 DatabaseMetaData的实现类
例如 MySQL的
public String getDatabaseProductName() throws SQLException {
try {
return "MySQL";
} catch (CJException var2) {
throw SQLExceptionsMapping.translateException(var2, this.getExceptionInterceptor());
}
}