You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis中空字符串转为null问题咨询:非空字段异常排查

MyBatis中空字符串被转为null的原因及解决办法

我来帮你拆解这个问题,这类情况在使用MyBatis自动生成的Example类时挺常见的,咱们先理清楚原因,再给出针对性的解决办法:

问题原因

  1. 默认类型处理器的行为:MyBatis默认使用的org.apache.ibatis.type.StringTypeHandler,在处理空字符串时,会默认将其转换为null值。当你把空字符串传入Example的条件方法(比如andAppVersionEqualTo)时,这个类型处理器会悄悄把空字符串换成null。
  2. MyBatis Generator的默认配置:如果是用MyBatis Generator生成的XXExample类,默认开启了trimStrings属性(值为true),它会自动去除字符串两端的空格,要是原字符串就是空字符串,处理后就会变成null。
  3. Example动态SQL生成逻辑:自动生成的Example类在构建SQL时,会对传入的参数做校验,空字符串可能会被判定为“无效值”,进而被替换成null参与SQL生成。

解决办法

1. 自定义String类型处理器(推荐)

创建一个自定义的类型处理器,覆盖默认的StringTypeHandler,让它保留空字符串:

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class NonNullStringTypeHandler extends BaseTypeHandler<String> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        // 直接传入空字符串,不转为null
        ps.setString(i, parameter);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getString(columnName);
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getString(columnIndex);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getString(columnIndex);
    }
}

然后在MyBatis配置文件中注册这个处理器:

<typeHandlers>
    <typeHandler handler="com.yourpackage.handler.NonNullStringTypeHandler" javaType="java.lang.String"/>
</typeHandlers>

2. 修改MyBatis Generator配置

如果是用Generator生成的Example类,在generatorConfig.xml里关闭trimStrings属性,避免空字符串被处理成null:

<javaModelGenerator targetPackage="com.yourpackage.model" targetProject="src/main/java">
    <!-- 关闭字符串自动修剪,保留空字符串 -->
    <property name="trimStrings" value="false"/>
</javaModelGenerator>

修改后重新生成XXExample类即可生效。

3. 代码层面手动规避

在设置Example条件前,手动确保空字符串能被正确传入:

XXExample example = new XXExample();
XXExample.Criteria criteria = example.createCriteria();
String appVersion = "";
// 直接传入空字符串,不做额外判断(前提是类型处理器或Generator配置已调整)
criteria.andAppVersionEqualTo(appVersion);

如果不想全局调整,也可以针对这个字段单独处理,比如空字符串时改用andAppVersionIsNotNull配合其他条件,但这种方式比较繁琐,适合临时场景。

4. 调整MyBatis全局配置

在mybatis-config.xml中设置jdbcTypeForNull为VARCHAR,让MyBatis在处理空值时以字符串类型传入:

<settings>
    <setting name="jdbcTypeForNull" value="VARCHAR"/>
</settings>

这个设置主要针对null值,但也能间接避免空字符串被强制转为null后引发的数据库非空约束报错。

内容的提问来源于stack exchange,提问作者Kenny Qiao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:43:00