web-dev-qa-db-ja.com

Java、SQL、ORMでmoneyデータ型を使用する方法

Javaアプリケーションでmoneyデータ型を使用する際のベストプラクティスは何ですか?moneyはdouble変数である必要がありますか?丸め、通貨などはどうですか?このための特別なライブラリはありますか?ORMとSQLはどうですか?最も人気のあるデータベースで。すべてのSQLエンジンでMoneyデータ型であるとは限りません。その場合、NUMERIC(15,2)DECIMAL(15,2)、またはREALデータ型を使用する必要がありますか?

19
bltc

Javaアプリケーションでmoneyデータ型を使用する際のベストプラクティスは何ですか?

BigDecimalを使用します。プリミティブを使用するとwill遅かれ早かれ精度の問題が発生します。

そして、最も人気のあるデータベースのORMとSQLについてはどうでしょうか。

Hibernate(およびおそらく他のすべて)はBigDecimalを問題なく処理できます。また、適切なデータベースタイプ(通常はDECIMAL)に変換されます。

21
jpkrohling

金銭的価値を表すには、BigDecimalを使用する必要があります。

Bloch、J.、Effective Java、第2版、アイテム48から:

floatおよびdoubleタイプは、0.1(またはその他の10の負の累乗)をfloatまたはdoubleとして正確に表すことができないため、金銭計算には特に適していません。

たとえば、$ 1.03があり、42cを費やしているとします。どれくらいのお金が残っていますか?

_System.out.println(1.03 - .42);
_

_0.6100000000000001_を出力します。

この問題を解決する正しい方法は、金額の計算にBigDecimalint、またはlongを使用することです。

SQLの場合、私はNUMERIC(19,2)を使用します。

18
dogbane

開発サークルでは、Javaでお金のためにBigDecimalを使用することが一般的にベストプラクティスと見なされています。ダブルIMHOを使用するよりも常に優れているとは限りませんが、BigDecimalから始めることをお勧めします。

SQLの場合、BigDecimalには一致するタイプNUMERICまたはDECIMALを使用し、doubleにはREALを使用することをお勧めします。

私が働いてきたすべての投資銀行と商社は、(C++とJavaで)お金の丸めで2倍に使用されたことは注目に値します。逆に、BigDecimalが使用されているのを見たことがありませんが、データベースでNUMERICが使用されているのを見たことがあります。アカウンティングの目的で、BigDecimalを使用します。

4
Peter Lawrey

正確な数値を格納するために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として格納されていたときに問題が発生しました。次に、double引数を持つBigDecimalコンストラクターが呼び出されました。 doubleから大きな小数を作成することは実際の慣行に反します。

上記のリンクの詳細と例!

0
Yan Khonski