DataX篇—Oracle支持Update模式

本文介绍了如何改造DataX以支持Oracle数据库的Update模式。作者在解决离线数据同步问题时发现Oracle的update模式不被支持,通过参考他人博客并分析源码,修改了`plugin-rdbms-util`模块,利用`merge into`语句实现update操作。修改包括在WriterUtil增加Oracle判断逻辑,调整getWriteTemplate方法及值绑定方法fillPreparedStatement,同时警告不支持包含CLOB字段的表。
摘要由CSDN通过智能技术生成

参考资料:https://blog.csdn.net/qq_27915891/article/details/107746629

前言

最近在做离线网络环境下数据同步,根据我们自己的业务改造阿里的开源框架DataX,发现其中遗留问题挺多的,其中就包括oracle的update模式它是不支持的,在我们beta1.0版本中,我们采用的是preSQL和postSQL来曲线Update数据的,这样虽然解决了问题,但是配置相对繁琐,由此参照大佬的博客,研究插件,改造了下源码,使Oracle插件支持update操作。

源码下载

https://github.com/qaz460472353/datax-plugin

源码目录结构

源码目录结构很清晰,一眼就能定位到想要的源码实现,我需要修改的是oralce相关所以就只关注oracle的目录
在这里插入图片描述

源码分析

1、代码很简单,一下就定位到OracleWriter这个类,并且定位到update模式不支持的判断
在这里插入图片描述
2、我们看到了DataX是将对数据库具体操作放到了一个叫plugin-rdbms-util的公共插件模块中。顺藤摸瓜,耐心看util或者write相关的代码,找到了核心位置代码WriterUtil,判断if(mysql) else other的地方,所以决定这里再加个orcle的判断
在这里插入图片描述

源码修改

1、既然核心位置已经找到,就要想用什么方法修改,mysql因为有天然的replace方案,所以update模式实现起来很方便,但是oracle没有,只能用merge into xx using xx on when matched then xx when not matched then xx去实现了,所以相对麻烦许多,不过好在也可以实现
2、 WriterUtil的getWriteTemplate增加Object objKey参数,这个主要是传的是write那边配置的pk,根据什么字段做update,然后下面增加一个else if(oralce)的逻辑代码

 else if(dataBaseType == DataBaseType.Oracle && writeMode.trim().toLowerCase().startsWith("update")){
   
            if(!(columnHolders.contains("id") || columnHolders.contains("ID")) && null == objKey){
   
                throw DataXException.asDataXException(DBUtilErrorCode.ILLEGAL_VALUE,
                        String.format("您所配置的 writeMode:%s 错误. 因为DataX 对oracle的update必须要有id主键或者指定的splitKey. 请检查您的配置并作出修改.", writeMode));
            }
            List<String> pkList = new ArrayList<>();
            if(null != objKey){
   
                pkList.addAll(Arrays.stream(objKey.toString().trim().split(",")).map(String::toUpperCase).collect(Collectors.toList()));
            }else {
   
                pkList.add("ID");
            }
            String pkCondition = StringUtils.join(pkList.stream()
                            .map(data -> new StringBuilder()
                            .append("(t1.").append(data.trim()).append("=").append("t2.").append(data.trim()).append(")").toString(
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值