项目 —— 历史数据脱敏加密

本文探讨了在已有历史数据的项目中如何实现用户名和手机号等敏感信息的加密,包括新数据和历史数据的加密策略。在历史数据加密过程中,采用一次性接口、数据库事务管理和分批处理来确保数据安全。同时,针对分页查询出现重复数据的问题,分析了MySQL5.6的优化器优化导致的不稳定排序,并提出了通过增加排序条件来确保查询一致性。

问题

在有历史数据的情况下,项目需要接入数据加密将用户名,手机号等敏感信息进行加密,如何处理?

解决

问题要点

主要分为两部分:新数据写入时的加密、历史数据加密。

新数据的加解密较为简单,不再赘述。

难点主要在历史数据的加密上,大致列出如下:

1、历史数据过多,分批处理。

2、历史数据加密失败问题。

思路总结

1、外放一个一次性的调用接口。

2、开启数据库事务(@Transactional或手动开启事务初始化),加密失败后,回滚。

3、数据分批处理

代码示例

外放接口

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("customer/aks")
public class AksExistDataController {

    private final AksExitDataUserIdServiceImpl aksExitDataUserIdServiceImpl;

    @PostMapping("encryptExist")
    public String encryptExist() {
        if (aksExitDataUserIdServiceImpl.aksABC()) {
            return "ABC表格已加密完成!   :)";
        } else {
            return "ABC表格已加密失败!   :(";
        }
    }
}

Mybatis事务

    public boolean aksABC() {
        TransactionStatus status;
		// 手动开启事务初始化
        status = transactionManager.getTransaction(new DefaultTransactionDefinition());
		//操作
        try {
            // 数据库完成操作后(例如业务上需先删除数据,再新增)
			encryptAksABC();
            // 操作无异常:提交事务
            transactionManager.commit(status);
            log.debug("表格{}已加密完成", "ABC");
            return true;
        } catch (Exception e) {
			log.debug("表格{}已加密出错", "ABC");
			e.printStackTrace();
            // 捕获异常时 事务回滚(避免先删除了数据在后续的操作中报错使得新增失败,而数据又被删了)
            transactionManager.rollback(status);
			log.debug("表格{}已回滚", "ABC");
			return false;
		}
    }

批量加密

    private final int size = 500;
   
    public void encryptAksLReadLog() {
        int totalNum = Integer.MAX_VALUE;
        for (int current = 1; (current - 1) * size < totalNum; current++) {
            Page<> page = new Page<>(current, size);
            IPage<ABC> abcList = aksUserIdDao.getAksLReadLog(page);
            totalNum = (int) abcList.getTotal();
            List<ABC> oriList = abcList.getRecords();
            if (oriList.size() != 0) {
                for (ABC ABC : oriList) {
                    //逐个加密
                }
            }
        }
	}

扩展阅读

Java、Mybatis事务——commit、rollback、编程式事务

问题
在分页查询时,发现不同页面的查询结果竟然有重复。

解决
在分页查询时,按照A字段进行排序,但某几个数据的A字段数值相同,导致分页出错,不同页面的查询结果有重复。

在MySQL 5.6的版本上,优化器在遇到order by limit语句的时候,做了一个优化,即使用了priority queue。使用 priority queue 的目的,就是在不能使用索引有序性的时候,如果要排序,并且使用了limit n,那么只需要在排序的过程中,保留n条记录即可,这样虽然不能解决所有记录都需要排序的开销,但是只需要 sort buffer少量的内存就可以完成排序。之所以5.6出现了第二页数据重复的问题,是因为 priority queue使用了堆排序的排序方法,而堆排序是一个不稳定的排序方法,也就是相同的值可能排序出来的结果和读出来的数据顺序不一致。

如果想要数据排序每次都相同的话,可以在order by后面再加一个排序条件,比如主键。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇宙超级无敌程序媛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值