« JavaMail:メール送信でOP25B対応 | トップページ | WebObjects:CSVレスポンスの実装 »

Java:MySQLに金額を格納する

データベースで金額を格納するのに適したデータ型として,MySQLでは「DECIMAL」型があります。FLOATやDOUBLEのような浮動小数点数の型では,小数点以下の値は近似値となりますが,DECIMALでは小数点以下の値も含めて正確に保存するために,MySQL5.0.3以前では数値を文字列に,5.0.3以降ではバイナリデータに変換して保存しています。「DEC」「NUMERIC」「FIXED」はDECIMALの別名です。
DECIMALフィールドの宣言は「DECIMAL(M,D)」です。Mはフィールド全体の桁数,DはMのうち小数点以下の桁数(スケール)を表します。DECIMALの最大桁数(DECIMAL(M,D)のMの値)は,MySQL5.0.3より前は1~254桁まで,5.0.6からは1~65桁までです。また,小数点以下の桁数(DECIMAL(M,D)のDの値)は0~30桁までです。(出典1)(出典2

MySQLにJavaプログラムからJDBCアダプタ(MySQL Connector/J)経由でアクセスする場合,データベースのDECIMAL型のフィールドは,JDBCによりJavaの「BigDecimal」クラスインスタンスに置き換えられます。
BigDecimalクラスでは,BigDecimalどうしでの四則演算のほか,小数点以下の桁数操作や丸め処理を行うことができます。BigDecimalで指定できる丸め処理は以下になります。

パラメータ名称説明
ROUND_UP切り上げ計算結果に端数があれば,端数を切り捨てて最小桁を+1(負の値のときは-1)します。
ROUND_DOWN切り捨て計算結果に端数があれば,端数を単に切り捨てます。
ROUND_CEILING正の無限大計算結果が正の値のときは切り上げ,負の値のときは切り捨てを行います。その結果,誤差は必ず正の方向に現れます。この指定は負の方向に誤差が出てはならない場合に指定します。
ROUND_FLOOR負の無限大計算結果が正の値のときは切り捨て,負の値のときは切り上げを行います。その結果,誤差は必ず負の方向に現れます。この指定は正の方向に誤差が出てはならない場合に指定します。
ROUND_HALF_UP四捨五入計算結果の端数が0.5より小さいときは切り捨て,0.5より大きいときは切り上げ,0.5のときは切り上げを行います。
注:連続して計算を行う場合には,四捨五入のみを指定して計算すると,計算結果の累積誤差が大きくなる欠点があります。そのため五捨六入と交互またはランダムに切り替えて誤差を抑えるなどの工夫が必要です。
ROUND_HALF_DOWN五捨六入計算結果の端数が0.5より小さいときは切り捨て,0.5より大きいときは切り上げ,0.5のときは切り捨てを行います。
ROUND_HALF_EVEN最近接偶数への丸め計算結果の端数が0.5より小さいときは切り捨て,0.5より大きいときは切り上げ,0.5のときは結果が偶数になるように切り上げまたは切り捨てを行います。
具体的には「0.5→0(切捨),1.5→2(切上),2.5→2(切捨),3.5→4(切上),4.5→4(切捨),5.5→6(切上)…」といった値になります。
連続して計算を行う場合に,累積誤差が出にくい丸め処理です。
ROUND_UNNECESSARY丸め無し計算結果で端数が生じる場合はArithmeticException例外をスローします。

●BigDecimalでの数値の比較
BigDecimal同士で数値を比較する場合,equalsメソッドでは数値としては同じでもスケールが違う値,たとえば「1」「1.0」「1.00」は別の値として判定されてしまいます。
これらを同じ値として比較判定する場合はcompareToメソッドを使います。

●BigDecimalでのゼロ値の判定
BigDecimalに設定された値がゼロかどうかを判定する場合,予めゼロ値を設定したBigDecimalとcompareToメソッドで比較判定する方法もありますが,それ以外に,BigDecimalのsignumメソッドが0を返すかどうかでも判定できます。signumメソッドは値が負の場合は-1,ゼロの場合は0,正の場合は1を返します。
予めゼロ値が設定されているBigDecimalとcompareToで比較したい場合は,Java1.5以降で「BigDecimal.ZERO」が定義されています。

■関連情報
MySQL:5.0.3以降のDECIMAL データ タイプの変更(MySQL5.1:22章:精密計算
MySQLの数値型:[4.1][5.1]
MySQL Connector/J:JDBCで値を受け渡すときのJavaの型:[5.0][5.1]
端数処理:(Wikipedia

■関連書籍をAmazonで検索:[MySQL][Java][JDBC]
MySQL徹底入門 第3版 ~5.5新機能対応~ (kindle本)



にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ プログラム・プログラマへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。
上新電機 パソコン買取サービスドミノ・ピザ【PC向けサイト】

|

« JavaMail:メール送信でOP25B対応 | トップページ | WebObjects:CSVレスポンスの実装 »

プログラミング」カテゴリの記事

MySQL」カテゴリの記事

Java」カテゴリの記事

トラックバック


この記事へのトラックバック一覧です: Java:MySQLに金額を格納する:

« JavaMail:メール送信でOP25B対応 | トップページ | WebObjects:CSVレスポンスの実装 »