Spring Boot项目中varchar字段为什么不用NULL?告别空指针从建表开始的重点在于把前置条件、操作顺序和容易误判的地方分清楚。
前言
在后端开发中,特别是当我们使用Spring Boot配合MySQL等关系型数据库时,经常会遇到一个看似微小但实则令人纠结的问题:“当用户的某个字符串字段没有填写时,数据库里到底该存
NULL还是存空字符串''?”今天我们就结合Spring Boot项目实例,来聊聊这个话题。
在决定用谁之前,我们必须先通过一个通俗的例子来看看这两者的本质区别。假设我们有一张用户表 user,其中有一个字段是 nickname(昵称)。
'':代表“确定的空值”。作为开发者,我们不仅关心理论,更关心写代码时会不会给自己挖坑。让我们看看在Spring Boot项目中,这两种选择会带来什么不同。
如果你的数据库存的是 NULL,在Java代码中处理不当,极易引发空指针异常。场景: 判断用户的昵称是否为空。如果存的是 NULL:
// 从数据库查出来的 user 对象Useruser= userMapper.selectById(1L);// 这里的 nickname 可能是 nullif (user.getNickname().isEmpty()) { // ... // 如果 nickname 是 null,调用 .isEmpty() 直接报错!NullPointerException!}为了安全,你不得不写出这样防御性的代码:
// 丑陋的防御性代码if (user.getNickname() != null && user.getNickname().isEmpty()) { // ...}// 或者使用工具类if (StringUtils.isEmpty(user.getNickname())) { // ...}如果存的是空字符串 '':
// 数据库查出来的 nickname 是 ""if (user.getNickname().isEmpty()) { // 安全!不会报错,逻辑正常执行 System.out.println("昵称为空");}结论: 使用空字符串 '',可以减少代码中大量的 null 检查,让代码更简洁,减少报错风险。
在使用 MyBatis-Plus 或 XML 写查询条件时,NULL 和空字符串的处理方式完全不同。场景: 查询所有没有设置昵称的用户。如果存的是 NULL:SQL语句必须写成:
SELECT*FROMuserWHERE nickname ISNULL;如果你写成 WHERE nickname = '',你一条数据也查不到。而且在 MyBatis XML 中,判断 NULL 需要格外小心:
<iftest="nickname != null"> AND nickname = #{nickname}</if><!-- 如果要查空的,通常还得单独处理 -->如果存的是空字符串 '':SQL语句非常统一:
SELECT*FROMuserWHERE nickname ='';这就和你查询普通数据(比如 WHERE nickname = '张三')的逻辑完全一致,不仅符合直觉,而且在拼接动态 SQL 时更加方便。
在 Spring Boot 中,我们通常使用 Jackson 进行 JSON 序列化返回给前端。 如果存的是 NULL: 返回的 JSON 可能是这样的:
{"id":1,"nickname":null}前端同学可能会跑来问你:“为什么这个字段是 null?我还要多写一层判断,能不能给我个空字符串?”或者,如果配置了 @JsonInclude(JsonInclude.Include.NON_NULL),这个字段直接就在 JSON 里消失了,前端还得处理字段丢失的情况。如果存的是空字符串 '':返回的 JSON 是这样的:
{"id":1,"nickname":""}看了上面的例子,你可能会觉得:“既然空字符串这么好用,那是不是要把所有的 varchar 都设为默认空字符串?”非也! 在以下场景中,NULL 才是正解。
假设有一个 remark(备注)字段。
''。NULL。如果你需要在业务上严格区分“用户主动清空了备注”和“系统还没录入备注”,那么 NULL 是必须的。虽然 MySQL 现在的版本优化了很多,但在某些老旧版本或特定数据库中,索引列如果存储大量空字符串 '',可能会导致索引效率问题。而 NULL 值通常不被计入索引(取决于数据库实现)。另外,在使用 COUNT() 函数时:
COUNT(nickname):如果全是 NULL,结果是 0;空字符串则会被计入统计。这会直接影响你的报表统计逻辑。说了这么多,到底该怎么选?这里给出一个简单粗暴的建议,适用于绝大多数 Spring Boot 业务开发:
对于绝大多数 varchar、text 类型的业务字段(如姓名、地址、描述、电话等):
''(空字符串)。NOT NULL。理由:
NullPointerException。= 和 != 查询,不需要区分 IS NULL。结语
技术选型没有绝对的对错,只有适不适合。 但为了团队协作的效率和代码的可维护性,“varchar 字段默认空字符串,NOT NULL” 确实能在多数情况下少踩些坑。
小米路由器插件安装失败解决方案(小米路由器插件安装失败怎么办)
小米路由器为什么无法成功安装插件(小米路由器安装插件失败怎么处理)
小米路由器为什么无法将电视屏幕投射到其他设备上(如何解决小米路由器无法进行电视投屏的问题)
小米路由器为什么无法连接电视网络(小米路由器和电视连接不上网络怎么办)
Spring Boot项目中varchar字段为什么不用NULL?告别空指针从建表开始
程序员如何自学?编程能够自学吗?