Как использовать тип данных денег в Java, SQL, ORM
Каковы наилучшие методы использования типа данных денег в приложении Java? Деньги должны быть в двойной переменной? Как насчет округления, валют и так далее. Для этого существуют специальные библиотеки? А как насчет ORM и SQL в большинстве популярных баз данных. Поскольку я не знаю, что во всех машинах SQL есть тип данных Money. В этом случае следует использовать NUMERIC(15,2)
, DECIMAL(15,2)
или тип данных REAL?
Ответы
Ответ 1
Каковы наилучшие методы использования типа данных денег в приложении Java?
Использовать BigDecimal. Использование любого примитива рано или поздно приведет к проблемам точности.
А как насчет ORM и SQL в большинстве популярных баз данных.
Hibernate (и, возможно, все остальные) может отлично обрабатывать BigDecimal. И это переводит на соответствующий тип базы данных, который обычно является DECIMAL.
Ответ 2
Вы должны использовать BigDecimal
для представления денежных значений.
От Блоха, Дж., Эффективная Java, 2-е изд., п. 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)
.
Ответ 3
В кругах разработки, обычно считается лучшей практикой использовать BigDecimal для денег на Java. Это не значит, что это всегда лучше, чем использование двойного ИМХО, но я бы предложил начать с BigDecimal.
Для SQL я предлагаю использовать соответствующий тип NUMERIC или DECIMAL для BigDecimal и REAL для double.
Стоит отметить, что все инвестиционные банки и торговые дома, в которых я работал, используют двойное с округлением денег (на С++ и Java). И наоборот, я никогда не видел BigDecimal, но я видел NUMERIC, используемый в базах данных. Для целей учета используйте BigDecimal.