在Java应用程序中使用money数据类型的最佳做法是什么?钱应该是双变量?四舍五入,货币等等。这是特殊的图书馆吗?那么在大多数流行的数据库中ORM和SQL呢?据我所知,并非所有SQL引擎都是Money数据类型。在这种情况下,应该使用NUMERIC(15,2)
,DECIMAL(15,2)
或REAL数据类型吗?
答案 0 :(得分:20)
在Java应用程序中使用货币数据类型的最佳做法是什么?
使用BigDecimal。使用任何原始将迟早会导致精度问题。
在大多数流行的数据库中,ORM和SQL怎么样?
Hibernate(可能还有其他所有人)可以很好地处理BigDecimal。它转换为适当的数据库类型,通常是DECIMAL。
答案 1 :(得分:18)
您应该使用BigDecimal
来表示货币价值。
来自Bloch,J.,Effective Java,2nd ed,Item 48:
float
和double
类型 特别不适合货币 计算,因为这是不可能的 表示0.1(或任何其他 负的权力为10)作为float
或 完全double
。例如,假设您有1.03美元 你花了42c。多少钱呢 你离开了吗?
System.out.println(1.03 - .42);
打印出
0.6100000000000001
。解决这个问题的正确方法是 使用
BigDecimal
,int
或long
用于货币计算。
对于SQL,我使用NUMERIC(19,2)
。
答案 2 :(得分:4)
在开发圈中,通常认为在Java中使用BigDecimal是最佳实践。这并不是说它总是比使用双恕我直言更好,但我建议你从BigDecimal开始。
对于SQL,我建议使用匹配类型NUMERIC或DECIMAL用于BigDecimal,将REAL用于double。
值得注意的是,我所使用的所有投资银行和交易公司都需要进行四舍五入(C ++和Java)。相反,我从未见过使用BigDecimal,但我在数据库中看到过NUMERIC。出于会计目的,请使用BigDecimal。
答案 3 :(得分:0)
请勿使用BigDecimal 来存储优先编号。
https://stackoverflow.com/a/54681006/4587961
现在提供一些示例。
double doubleValue = 35.7;
BigDecimal fromDouble = new BigDecimal(doubleValue);
BigDecimal fromString = new BigDecimal("35.7");
boolean decimalsEqual = fromDouble.equals(fromString);
System.out.println("From double: " + fromDouble + " " + fromString.stripTrailingZeros().toPlainString());
System.out.println("decimalsEqual: " + decimalsEqual");
打印
From double: 35.7000000000000028421709430404007434844970703125 35.7
decimalsEqual: false
当在mongo中将大十进制存储为双精度时,我也遇到了麻烦。然后调用具有双参数的BigDecimal构造函数。从double中创建一个大的十进制是违反实际做法的。
上面的链接中有更多详细信息和示例!