Oracle Varchar2 存储中文的长度和 @Valid 校验注意事项

背景

项目对所有录入数据的实体都用 Spring 的 @Validated 进行了校验,集成测试的时候却总是出现校验通过、入库异常的问题。

记得开发的时候测试过入参校验,怎么突然就失效呢?还一度怀疑自己失忆了,纳闷 @Validated 校验怎么就失效了呢?

Oracle Varchar2 存储中文的长度

碰到一个问题 Spring 的 @Validated 校验通过,但数据库插入时报超长。突然意识到是中文的问题,Oracle 存储中文时,一个中文的长度是 2

解决办法: @Validated 校验的长度不能跟数据库长度一样,应该设置为数据库长度的一半

另外,文本编辑器 EditPlus 显示列的时候,一个中文是占据两列的。测试的时候通过 EditPlus 输入中文,看列数,以为输入的汉字个数跟列数一致,没料到它跟 Oracle 一样。

太依赖工具了,没想到是数据长度的问题,跟踪方向一直放在了 @Validated 校验失效上了!

复盘解决这个问题的过程

为了解决这个中文长度的存储问题,尝试的过程如下:

  1. 怀疑是项目包引用问题,回溯项目提交日志,看看有什么变化,没变化。
  2. @Validated 失效的各种可能的原因及解决办法,未果。SpringBoot 用的是2.1.6 自带了校验包,不是网上常见的原因。
  3. 写了一个 HellWorld 的测试类,Validated 标签是能正确校验的。然后调整真实的实体,对某个字段添加一个 @NotEmpty,请求参数中对应字段为空时,返回了校验失败信息,说明还是校验是生效的。
  4. 能校验,为什么数据入不了库呢?把测试数据拷贝到 EditPlus 中,打算认真数一数的时候,发现光标移动一个汉字时,列数增加了 2:

在这里插入图片描述 终于意识到是数据的问题,中文汉字没有超长,但数据库存储却超长了

启示录

对于所有的业务实体类,都通过 @Size 指定了数据长度,保证在执行 SQL 之前先过滤掉无效数据,长度最初是与数据库表字段的长度一致的。

但是 Oracle 对于中文,一个汉字的长度记为 2,所以在结合 @Validated 校验数据时,需要注意中文长度,我采用的方式是将 @Validated@Size 范围调小为数据库字段长度的一半,可以保证中文最长时能够顺利入库。

猜你喜欢

转载自juejin.im/post/7041529422624587813
今日推荐