Mybatis的批量插入Bigdecimal会丢失精度

分析

MyBatis在批量插入BigDecimal类型的数据时,可能会出现精度丢失的问题。这主要是由于Java的BigDecimal类型和数据库的DECIMAL或NUMERIC类型之间的精度差异造成的。

Java的BigDecimal类型用于表示精确的浮点数,可以指定任意的精度(小数点后的位数)。而数据库中的DECIMAL或NUMERIC类型也有精度的概念,但是它们通常有一个固定的精度限制,比如DECIMAL(10, 2)表示总共有10位数,其中小数点后有2位。

当你尝试将一个高精度的BigDecimal值存储到数据库中的低精度的DECIMAL或NUMERIC字段时,就可能出现精度丢失的问题。

为了解决这个问题,可以考虑以下几点:

确保精度匹配:确保你的Java代码中的BigDecimal的精度与数据库字段的精度匹配。如果数据库字段的精度较低,那么在插入数据之前,你可以通过BigDecimal的setScale方法来设置合适的精度。
使用适当的数据库类型:如果可能的话,可以考虑使用数据库支持的高精度数值类型,如PostgreSQL的NUMERIC类型或MySQL的DECIMAL类型,它们可以支持更高的精度。
自定义类型处理器:你可以创建一个自定义的类型处理器(TypeHandler),在插入和查询时,对BigDecimal进行适当的精度处理。
下面是一个简单的例子,展示了如何在MyBatis中使用自定义的类型处理器来处理BigDecimal:

public class BigDecimalTypeHandler extends BaseTypeHandler<BigDecimal> {  
  
    @Override  
    public void setNonNullParameter(PreparedStatement ps, int i, BigDecimal parameter, JdbcType jdbcType) throws SQLException {  
        // 设置合适的精度,这里设置为2位小数  
        BigDecimal scaledValue = parameter.setScale(2, BigDecimal.ROUND_HALF_UP);  
        ps.setBigDecimal(i, scaledValue);  
    }  
  
    @Override  
    public BigDecimal getNullableResult(ResultSet rs, String columnName) throws SQLException {  
        BigDecimal value = rs.getBigDecimal(columnName);  
        return value;  
    }  
}

在你的MyBatis配置文件中,注册这个自定义类型处理器:

<typeHandlers>  
  <typeHandler handler="com.example.BigDecimalTypeHandler" javaType="java.math.BigDecimal" jdbcType="DECIMAL"/>  
</typeHandlers>

这样在处理BigDecimal类型的数据时,MyBatis就会使用你的自定义类型处理器,从而避免精度丢失的问题。

实战

下面这种批量插入的时候

<foreach collection="list" item="item" separator=",">
#{item.useWorkingHours,jdbcType=DECIMAL}
</foreach>

useWorkingHours是decimal类型,在插入多条数据,取值如 0.1,0.81时 数据0.81会都变成0.8,丢失精度

网上的解决方案:

 cast(#{item.weeklyInputPercentage,jdbcType=DECIMAL} as decimal(10,2))

对我没用效果

在代码里面去改

workingHoursManagement.setWeeklyInputPercentage(workingHoursManagement.getWeeklyInputPercentage().setScale(2, RoundingMode.HALF_UP));

解决了

总结

MyBatis批量插入BigDecimal的原理主要涉及到JDBC的批处理技术和Java的BigDecimal类型。

JDBC批处理技术:JDBC(Java Database Connectivity)是Java中用于连接和操作数据库的一种技术。在JDBC中,为了提高数据库插入、更新等操作的效率,提供了一种叫做批处理(Batch Processing)的技术。在批处理中,多个数据库操作被打包成一个批次,一次性发送给数据库服务器,减少了网络传输的次数,提高了效率。
Java BigDecimal类型:BigDecimal是Java的一个类,用于对超大的浮点数进行运算。BigDecimal可以准确地表示小数,包括那些接近但不等于1的小数,避免了浮点数运算的精度问题。
在MyBatis中,当你要插入大量BigDecimal类型的数据时,可以使用批处理技术来提高效率。你可以通过以下步骤来实现:

创建SqlSession:SqlSession是MyBatis中用于执行SQL的主要接口。你可以通过SqlSession的批量操作(executeBatch)来执行批处理。
构建SQL语句:使用MyBatis的XML映射文件或注解来构建SQL语句。在SQL语句中,使用Java的BigDecimal类型来表示要插入的数据。
执行批处理:通过SqlSession的批量操作(executeBatch)来执行SQL语句。在执行批处理时,多个SQL语句会被打包成一个批次,一次性发送给数据库服务器。
关闭SqlSession:在执行完批处理后,要关闭SqlSession以释放资源。
需要注意的是,虽然批处理技术可以提高效率,但是如果一次插入的数据量太大,可能会消耗过多的内存。因此,在执行批处理时,要注意控制批次的大小,以避免内存溢出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

渐暖°

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

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

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

打赏作者

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

抵扣说明:

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

余额充值