java在MySQL中存储美元金额:INT vs LONG vs BIGINT
我正在构建一个数据库,需要在其中存储货币值。我将货币值存储为美分($100.00=10000)。因此,我决定不使用INT
来存储货币值(带符号的int仅限于存储$21,474,836.48
)
我看到MySQL还有两种类似的类型:BIGINT
和LONG
在研究之后,我无法找出其中的区别,于是我决定使用BIGINT
。但当我去写准备好的声明时:
int id = ...;
BigInteger amount = ...;
String sql = "insert into transaction(id, amount) VALUES(?,?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, id);
if(amount == null)
pstmt.setNull(2, java.sql.Types.BIGINT);
else
pstmt.setBigInteger(2, amount); // <---- This method does not exist
没有PreparedStatement::setBigInt()
方法。唯一存在的PreparedStatement
方法是setInt()
、setLong()
和setBigDecimal
于是,我改变了我的决定,决定改用LONG
,但当我去写同样的代码时,我注意到:
int id = ...;
BigInteger amount = ...;
String sql = "insert into transaction(id, amount) VALUES(?,?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, id);
if(amount == null)
pstmt.setNull(2, java.sql.Types.LONG); // <---- This java.sql.Type does not exist
else
pstmt.setLong(2, amount.longValue());
因此PreparedStatement
没有setBigInt
(或setBigInteger
)方法,并且java.sql.Types
包不包含LONG
枚举
问题是:
- 在MySQL级别上
BIGINT
和LONG
之间有什么区别?哪个更适合储存货币李> - 如果我在
BIGINT
列上使用PreparedStatement::setLong
,会发生什么李> - 这也引出了一个问题,如果我在
BIGINT
列上使用PreparedStatement::setBigDecimal
,会发生什么李>
编辑/更新:
我为这个糟糕的问题道歉。我不知道MySQL甚至没有LONG
数据类型。部分原因是我用来构建数据库的数据建模器(MySQL自己的:MySQL Workbench)允许您将LONG
设置为数据类型。但是,当您对数据库进行正向工程时,它会将LONG
更改为BIGINT
(图片来自MySQL Workbench datamodeler,我正在使用它来帮助构建我的数据库)
# 1 楼答案
^{} 的定义如下:
在Integer Types下,MySQL手册记录了它的}(及其关联的包装类^{} )也表示一个8字节的整数
BIGINT
数据类型是一个8字节(即64位)的整数。Java primitive datatype{因此,如Mapping SQL and Java Types所述:
在^{} 中没有
LONG
常量,MySQL也没有LONG
数据类型都不是。使用^{} 定点数据类型将美元金额存储为离散十进制值。如果您坚持以整数类型存储分金额,“正确”答案仅取决于您希望支持的预期值范围
这正是应该设置} 所述:
BIGINT
参数值的方式。如^{如^{} 所述:
因此,Java将把您的值作为^{} (定点十进制)数据类型发送到MySQL。MySQL随后将按照Type Conversion in Expression Evaluation中的描述执行类型转换:例如,如果您只是将值存储在
BIGINT
列中,则该值将转换为BIGINT
存储。如果该值在BIGINT
的范围内,则不应注意到任何不良影响(小数部分丢失除外)