mysql decimal 字段在 java 中必须映射为 java.math.bigdecimal 才能保证精度,使用 float、double 或 int/long 会导致精度丢失;jdbc 应用 rs.getbigdecimal() 获取,orm 框架需正确配置 bigdecimal 类型及 precision/scale。

MySQL 的 DECIMAL 字段在 Java 中必须映射为 java.math.BigDecimal,这是唯一能保证精度不丢失的正确方式。
直接用 float、double 或 int/long 接收 DECIMAL 数据,会导致隐式类型转换和精度误差——尤其在金额、利率、库存数量等业务场景中,这种误差不可接受。
✅ 正确映射方式
-
数据库字段定义示例:
CREATE TABLE orders ( id INT PRIMARY KEY, amount DECIMAL(15,2), -- 总共15位,小数占2位(如 9999999999999.99) tax_rate DECIMAL(5,4) -- 如 0.0825(税率) ); -
Java 实体类对应字段:
public class Order { private Integer id; private BigDecimal amount; // ← 必须是 BigDecimal private BigDecimal taxRate; // ← 同样用 BigDecimal // getter/setter... } -
JDBC 查询时获取值:
ResultSet rs = stmt.executeQuery("SELECT amount FROM orders WHERE id = 1"); if (rs.next()) { BigDecimal amount = rs.getBigDecimal("amount"); // ✅ 正确:直接获取 BigDecimal // 不要用 rs.getDouble("amount") 或 rs.getString("amount") 再转 —— 容易出错 }
⚠️ 常见错误与规避方法
-
错误写法:
double d = rs.getDouble("amount"); // ❌ 浮点误差(如 19.99 变成 19.989999999999998) String s = rs.getString("amount"); // ❌ 字符串虽准,但多一层转换风险 BigDecimal b = new BigDecimal(rs.getDouble("amount")); // ❌ double 构造器自带精度污染 -
正确写法(推荐):
BigDecimal b = rs.getBigDecimal("amount"); // ✅ 最安全 // 或明确用字符串构造(仅当不得不从 String 入手时): BigDecimal b = new BigDecimal(rs.getString("amount")); // ✅ 字符串无精度损失
? 注意:
BigDecimal.valueOf(double)是安全的,因为它内部调用了Double.toString(),避免了new BigDecimal(double)的陷阱。
? ORM 框架(如 MyBatis / JPA)中的配置要点
MyBatis:默认支持
DECIMAL → BigDecimal自动映射,无需额外配置。确保 resultType 或 resultMap 中字段类型为java.math.BigDecimal。-
JPA / Hibernate:
@Column(precision = 15, scale = 2) private BigDecimal amount; // ✅ JPA 会自动绑定到 DECIMAL(M,D)
precision对应 MySQL 的M,scale对应D;Hibernate 生成建表语句时也会匹配为DECIMAL(15,2)。
? 小数位对齐建议(避免显示异常)
MySQL 的 DECIMAL(10,2) 存的是精确值(如 123.00),但 Java 中 BigDecimal 默认可能省略末尾零(如 .toString() 输出 "123")。若需保持格式一致:
// 保留两位小数(四舍五入或直接补零) amount.setScale(2, RoundingMode.HALF_UP); // 如 123 → 123.00 // 或格式化输出(非存储用) String formatted = amount.setScale(2, RoundingMode.HALF_UP).toString();
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











