mybatis BigDecimal货币类型的值不能保存为0的问题

在debug调试时,实体类balance接收到值为0,但执行Update sql语句时balance字段未更新,猜测可能是BigDecimal为0的值和空字符串适配问题。后续开发中,使用int类型也出现相同问题,float和double类型未测试。
mybatis xml中之前的写法
<if test="balance != null and balance!=''">
   balance = #{balance},
</if>

更改后的写法

<if test="balance != null">
   balance = #{balance},
</if>

在debug调试的时候实体类balance其实是接收到了值为0,但是执行Update sql语句的时候发现balance字段并没有更新。自己猜想可能是bigdecimal为0的值和空字符串适配了,自己也不是很懂是什么原因,有知道的大佬麻烦解答一下,非常感谢

追加:在后来的开发中用int类型的时候也出现相同问题,float double还未试过

 

### MyBatis BigDecimal 类型 Null 处理方法 当使用 MyBatis 进行数据库操作时,遇到 `BigDecimal` 类型的字段,在某些情况下可能会被错误地识别为 `null`。这主要是因为 MyBatis类型处理器在处理特定数(如零)时的行为所致。 对于 `BigDecimal` 类型为零的情况,MyBatis 有时会将其视为 `null` 处理[^1]。为了避免这种情况的发生,可以采取以下几种措施: #### 方法一:显式调用 toString() 通过将 `BigDecimal` 对象转换为其字符串表示形式再传递给 SQL 查询,能够有效防止该对象因为空而被认为是 `null`。例如: ```java // Java代码片段 public void insert(BigDecimal amount){ String strAmount = (amount != null)? amount.toString(): "0"; mapper.insert(strAmount); } ``` 这种方法简单直接,但在业务逻辑层面上增加了额外的操作,不是最优解法。 #### 方法二:自定义 TypeHandler 更推荐的做法是在 MyBatis 中注册一个针对 `BigDecimal` 类型的自定义 `TypeHandler` 来确保正确的映射关系。创建一个新的类继承自 `BaseTypeHandler<BigDecimal>` 并重写相应的方法: ```java import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.math.BigDecimal; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class BigDecimalZeroAsNullTypeHandler extends BaseTypeHandler<BigDecimal> { @Override public void setNonNullParameter(PreparedStatement ps, int i, BigDecimal parameter, JdbcType jdbcType) throws SQLException { if (parameter.compareTo(BigDecimal.ZERO) == 0 || parameter != null) { ps.setBigDecimal(i, parameter); } else { ps.setNull(i, java.sql.Types.DECIMAL); } } @Override public BigDecimal getNullableResult(ResultSet rs, String columnName) throws SQLException { return rs.getBigDecimal(columnName); } @Override public BigDecimal getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return rs.getBigDecimal(columnIndex); } @Override public BigDecimal getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return cs.getBigDecimal(columnIndex); } } ``` 接着需要配置此处理器应用于相应的实体属性上: ```xml <!-- XML Mapper 文件 --> <mapper namespace="com.example.mapper.YourMapper"> <!-- 使用自定义type handler --> <resultMap id="baseResultMap" type="your.package.model.YourModel"> ... <result column="column_name" property="propertyName" typeHandler="com.yourpackage.handler.BigDecimalZeroAsNullTypeHandler"/> ... </resultMap> </mapper> ``` 这样做不仅解决了问题,还提高了代码可维护性和扩展性。 #### 方法三:调整SQL语句条件判断 另一种解决方案是修改 SQL 映射文件中的 `<if>` 测试表达式,使其更加严格地检查输入参数是否确实为 `null` 或者等于零。比如: ```xml <select id="selectByCriteria" resultType="YourModel"> SELECT * FROM table WHERE 1=1 <if test="propertyValue != null and !propertyValue.equals(new java.math.BigDecimal('0'))"> AND column_name >= #{propertyValue} </if> </select> ``` 这种方式可以在不改变现有架构的前提下快速修复已知的问题实例。 以上三种方案都可以有效地解决 MyBatis 在处理 `BigDecimal` 类型时可能出现的 `null` 错误情况。选择哪种取决于项目的具体情况和个人偏好。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值