阿里云开发者社区

电脑版
提示:原网页已由神马搜索转码, 内容由developer.aliyun.com提供.

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

2024-05-07300
版权
版权声明:
本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议》和 《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
简介: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以释放资源。

需要注意的是,虽然批处理技术可以提高效率,但是如果一次插入的数据量太大,可能会消耗过多的内存。因此,在执行批处理时,要注意控制批次的大小,以避免内存溢出。

目录
相关文章
|
1月前
|
存储SQLJava
MyBatis batchInsert 批量插入数据
MyBatis batchInsert 批量插入数据
4600
|
4月前
|
SQL存储Kubernetes
Seata常见问题之mybatisplus的批量插入方法报SQL错误如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
|
4月前
|
SQLJava数据库连接
Mybatis查询的时候BigDecimal类型的值查询失效的解决办法
Mybatis查询的时候BigDecimal类型的值查询失效的解决办法
|
SQLJava数据库连接
MyBatis痛点验证,使用 foreach 批量插入慢?
MyBatis痛点验证,使用 foreach 批量插入慢?
29900
|
4月前
|
存储Java数据库连接
MyBatis Plus中的批量插入:通过开启rewriteBatchedStatements=true
MyBatis Plus中的批量插入:通过开启rewriteBatchedStatements=true
54800
|
4月前
|
Java数据库连接mybatis
mybatis 批量插入
mybatis 批量插入
|
SQLJava数据库连接
如何使用Mybatis实现批量插入 ?
如何使用Mybatis实现批量插入 ?
7500
|
小程序Java数据库连接
【实践】mybatis批量插入map
【实践】mybatis批量插入map
55100
|
SQL缓存JavaScript
从120s到2.5s!看看人家的MyBatis批量插入数据优化,那叫一个优雅! 下
从120s到2.5s!看看人家的MyBatis批量插入数据优化,那叫一个优雅! 下
|
SQLJava数据库连接
从120s到2.5s!看看人家的MyBatis批量插入数据优化,那叫一个优雅! 上
从120s到2.5s!看看人家的MyBatis批量插入数据优化,那叫一个优雅! 上

热门文章

最新文章