Java 刚入职,做数据迁移,之前没接触过,现在有个需求,想了好久还是没有解决,能不能求大佬们帮忙看看,谢谢

2019-06-20 11:26:13 +08:00
 pengyOne

项目要求是这样的:

数据库中有几十个表,现在我要给其中大约一半的表增加两个字段,一个最后修改时间 LAST_CHANGE_TIME 和同步状态 SYNC_STATUS(0 或 1 同步过后变为 1).现在要求这些表每进行插入跟新操作,就同步更新同条记录的最后修改时间 LAST_CHANGE_TIME 和同步状态 SYNC_STATUS 变为 0.

因为这是一个老项目,所以其他部分的增删改查都已经写好了.但公司不让我对原代码进行修改,而且也不能用触发器进行同步的修改操作.这就是我烦躁的原因.

公司给出的方案是用 druid 的 filter 来操作,具体没有写.....

然后我就尝试改写 druid 的 filter 里的 statementExecuteAfter 动态获取表名再进行修改操作,但是操作后发现,这种改写不能动态引入主键 ID 值来针对一条数据(我在外部定义可变 ID 进行修改,然后在重写的方法里引入,然而这个 ID 不管怎么改变,重写的方法里的 ID 都只会是第一个值).废了,不知道有没有大佬知道 druid 有什么针对这种的解决方案.....

也尝试过 AOP 来解决,但是这些包扫描是个大问题,因为这个数据库可能有上百个表,而我这里只要修改不到二分之一的表而已,即使扫描全部,joinpointer 倒是可以获取传入的修改条件即 ID,但我却不知道怎么获取此次操作针对的是哪个表? 所以也陷入僵局...

我很菜,这种需求我各种搜索也没找到解决的方法....求各位大佬帮忙看看怎么解决,给个思路,即使不是 druid 的 fiter 方案也好啊...我快被逼疯了
3749 次点击
所在节点    程序员
32 条回复
Cooky
2019-06-20 11:33:42 +08:00
不能改代码,不能用触发器,那还同步个鸡巴?
难不成一直扫描数据库?
zhangalong69
2019-06-20 11:39:08 +08:00
把这些表先都找找出来,用 python 脚本执行添加属性的操作,然后对单个表用小工具代码添加字段,比如打个 java 工程直接在生产环境添加,一张表一次取 1000 个数据,单线程多线程都可以
pengyOne
2019-06-20 11:42:23 +08:00
@Cooky 同步数据是每天定时同步.....最主要的就是原数据库那块同步状态的修改问题,因为可能对已有数据进行修改,然后就要改变它的状态从 1 变 0.....
新增数据,我就直接给时间和状态设置默认值了,但修改数据的时候这两个字段的修改真的是......不会
我也觉得很烦躁,这边还给我个思路说,中途拦截 sql 然后修改 sql 再继续执行.....而这我也不会啊,druid 有这种操作吗?
securityCoding
2019-06-20 11:49:45 +08:00
订阅 binlog?
pengyOne
2019-06-20 11:56:41 +08:00
@zhangalong69 emmmmm 字段添加很快就完成了.....我的疑惑是怎么更新的问题
lazyfighter
2019-06-20 12:02:52 +08:00
LAST_CHANGE_TIME 可以在字段表达式完成 同步状态感觉没啥用,完全可以根据时间进行同步
rockyou12
2019-06-20 12:12:21 +08:00
看你有 aop 应该是 java+spring boot,可以在 dao 层的 insert、save 这些方法入手做 aop,直接把对象拿出来,反射获取字段 LAST_CHANGE_TIME 和 SYNC_STATUS 然后修改字段的值
xxxy
2019-06-20 12:14:39 +08:00
在原代码和数据库间加一层代理?
pengyOne
2019-06-20 12:34:53 +08:00
@rockyou12 这应该不行,因为源代码那边的对象是没有我新增的这些字段的....而且这项目有些用 xml,有些直接用 @
query,好像还有 hibernate????
pengyOne
2019-06-20 12:46:45 +08:00
@lazyfighter 判定时间确实可以耶,不过领导说要状态就用状态了吧........字段表达式是啥?可以做到在进行跟新操作后对该条数据修改吗?
tomczhen
2019-06-20 13:37:19 +08:00
这不就是 CDC 么。
hand515
2019-06-20 13:38:17 +08:00
用 canal 订阅 binlog 应该可以解决
endershadow
2019-06-20 13:39:32 +08:00
canal 完美解决你的问题
lazyfighter
2019-06-20 13:49:19 +08:00
@pengyOne `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
lazyfighter
2019-06-20 13:51:55 +08:00
刚刚百度了一下 mybatis 可以写拦截器修改 sql,那你的标志位也就解决了
rqxiao
2019-06-20 13:54:29 +08:00
hibenate 有个 listener ?
x66
2019-06-20 13:59:45 +08:00
数据库 update time 字段设置成 update 的时候自动更新不就行了吗?然后根据 update time 捕捉变化数据
EasyProgramming
2019-06-20 14:05:29 +08:00
emmm,看需求描述,好像不是数据迁移呀?
LuVx
2019-06-20 14:30:25 +08:00
如果不使用的 mysql 呢, ON UPDATE CURRENT_TIMESTAMP 也就没效果了, 最有效的感觉还是 lazyfighter 提出的拦截改写 sql, 或者用 canal(实时性要求不高的话)
pengyOne
2019-06-20 14:58:33 +08:00
@hand515
@endershadow 我这用的是 oracle 能用这 canal 吗?我看百度好像说这是操作 mysql 的,而且也没什么示范的实例

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/575757

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX