Oracle适配Mysql一遍过(databaseId方案)

应用场景之前架构大部分都是引入一种数据源进行数据的处理,而随着服务越多,生产场景和个性化的需要,在项目中使用mybatis兼容mysql与oracle已经成为了一个开发人员必备的知识储备,有助于在生产环境进行数据源mysql/oracle的切换。

这里将介绍一种简单而且适合小白快速上手的一种方案–databaseId数据库厂商标识。这个方案将分三步进行配置
第一步:引入数据源

这里我们可以通过yml文件引入datasource(数据源以mysql为例,如果要引入oracle在yml文件引入即可)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xxx...
    type: xxx
    username: xxx
    password: xxx
    driver-class-name:xxx
第二步:配置@Bean

新建一个配置类进行注入@Bean(配置类记得加上@Configuration)–让项目知道走哪个databaseId

@Bean
public DatabaseIdProvider getDatabaseIdProvider() {
    DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
    Properties p = new Properties();
    p.setProperty("Oracle", "oracle");
    p.setProperty("MySQL", "mysql");
    databaseIdProvider.setProperties(p);
    return databaseIdProvider;
}
第三步:添加databaseId=“mysql”/"oracle"即可完成

在mapper中进行sql厂商标识的注入

<!--第一种:复制两个片段直接加上databaseId="mysql"/"oracle"-->
<select id="selectAllCoco" resultType="com.note.note.pojo.Coco" databaseId="mysql">
  select id,name from cocodb;
</select>
<select id="selectAllCoco" resultType="com.note.note.pojo.Coco" databaseId="oracle">
  select id,name from cocodb;
</select>
<!--第二种:引入if test = "mysql"/"oracle" databaseId="mysql"/"oracle" 进行改写-->
<insert id="insert">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    <if test="_databaseId == 'oracle'">
      select seq_users.nextval from dual 
    </if>
    <if test="_databaseId == 'db2'">
      select nextval for seq_users from sysibm.sysdummy1" 
    </if>
  </selectKey>
  insert into users values (#{id}, #{name})
</insert>
源码解读:为什么加上DataSourceId=“mysql”/"oracle"就可以匹配对应的机制呢?
1.使用mybatis就需先创建sqlSessionFactory接口对象org.apache.ibatis.session.defaults.DefaultSqlSessionFactory
内部包含org.apache.ibatis.session.Configuration属性,即mybatis-config配置文件信息,包括数据源、拦截器、插件、别名等
2.spring整合mybatis从SqlSession类型bean初始化进行解析时MyBatis根据数据库连接池获取到数据库厂商标识,然后按照映射关系过滤掉databaseId不匹配的statement语句,最后都放到org.apache.ibatis.session.Configuration#mappedStatements这个Map类型的属性当中
3.当业务请求的时候,调用xxMapper#selectAll接口的时候,只会映射到一个语句了。如果存在多个,首先根据databaseId匹配,然后在匹配没有databseId的,已经有匹配成功的则忽略。
扩展:oracle与mysql语句间的改写(mapper语句改写重点!!!)
1.oracle语法中的listagg语法–对应mysql的group_concat语法
--oracle--
listagg(label_id,',') WITHIN GROUP (ORDER BY audit_id) AS  label_ids
--mysql--
group_concat(label_id order by audit_id ) as label_ids
2.oracle改造时间/to_char/trunc/nvl/add_month等函数**
--oracle--
nvl((sum(is_this_month) - sum(is_last_month)),0) as month_count
--mysql--
sum(ifnull(is_this_month,0)) - sum(ifnull(is_last_month,0)) month_count
--oracle--
to_char(TRUNC(add_months(trunc(sysdate), -1), 'MM'), 'MM') = to_char(VALID_DATE, 'MM')
    then 1 else 0 end as is_last_month
--mysql--
Month(now() - 1) = Day(VALID_DATE) then 1 else 0 end is_last_month
--oracle--
when to_char(sysdate, 'MM') = to_char(VALID_DATE, 'MM')
--mysql--
Month(now()) = Month(VALID_DATE)
--oracle--
TRUNC(ADD_MONTHS(sysdate, -1), 'mm')
--mysql--
month(now()-1))
我是uu,今天的分享就到此啦,欢迎大家指正!
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值