1
ProgrammerAlan 2023-02-13 15:51:17 +08:00
public class CustomSQLInterceptor implements Interceptor {
@Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); BoundSql boundSql = statementHandler.getBoundSql(); String sql = boundSql.getSql(); if (sql.contains("mobile =")) { // 对 SQL 进行修改 sql = sql.replace("mobile =", "mobile in"); sql = sql.replace("'", "('"); sql = sql + "', '密文')"; // 使用新的 SQL Field field = boundSql.getClass().getDeclaredField("sql"); field.setAccessible(true); field.set(boundSql, sql); } return invocation.proceed(); } @Override public Object plugin(Object target) { if (target instanceof StatementHandler) { return Plugin.wrap(target, this); } return target; } @Override public void setProperties(Properties properties) { } } |
2
ProgrammerAlan 2023-02-13 15:54:29 +08:00
@ProgrammerAlan ChatGPT 给出的答案,使用 Mybatis 拦截器改写 SQL
|
3
paopjian 2023-02-13 16:00:35 +08:00 1
为什么不新建一张表,新数据放新表,旧数据修改好后再放新表里,最后删除?
|
4
jomalonejia 2023-02-13 16:09:01 +08:00
新字段 or 新表 先保证库里有数据 再调整业务逻辑 over
|
5
blubzz 2023-02-13 16:18:00 +08:00
建议表新增加密字段,代码增加双写逻辑,同时保存明文和密文,但查询逻辑还是用明文字段。
然后历史数据加密跑批,最后再切换使用密文查询。 |
6
sxfscool 2023-02-13 16:23:41 +08:00
加新字段吧
|
7
Wh1te OP |
8
Wh1te OP @ProgrammerAlan #1 这个直接字符串替换感觉不太行,如果 SQL 有个换行或者用了别名联表啥的,就 GG 了
|
9
heysnakelis 2023-02-13 18:06:35 +08:00
根据手机号码的最后一个数字 逐步清洗,先清尾号 1 的数据,然后写 sql 的时候如果尾号 1 就走加密查询,尾号不是就原手机号查询,分配清洗替换?
|
10
season8 2023-02-13 18:20:46 +08:00
如你所说,就一个用户表需要加密,那代码量应该不多吧,硬改工作量应该还好,就硬改呗。
|
12
dog82 2023-02-14 10:46:26 +08:00
2 楼说的用拦截器是个好思路,就是不知道拦截规则怎么定义
|
13
Wh1te OP @dog82 #12 是的,我说的 mybatis 插件就是 mybatis 的拦截器,我想问的是这个 SQL 改写逻辑要怎么实现
|
14
echoless 2023-02-18 16:08:54 +08:00
@Wh1te 手机号在业务上又是有精确查询的需求,很多 SQL 都有 mobile = 'xxxxxx' 的查询条件
` where mobile = encrypt_mobile('xxxxxx') encrypt_mobile 是个 function 写到 database 里面, 或者利用 database 已有的函数. ` |
15
echoless 2023-02-18 16:14:13 +08:00
上面的作废, 没读完.
sql 改写 如果你通过的是 orm 可以在 orm 层做. 该 raw sql, 可以解析 sql, 找到有 mobile 筛选条件, 去替换. (如果 sql 不多, 人工更简单吧) |