Mysql字段类型和Java类型的对应关系

文章目录

    • 一. 问题复现
      • 1. mapper.xml
      • 2. dao.java
      • 3. manager.java
    • 二. 问题解答
      • 1. 原因概述
      • 2. 原因解读
    • 参考资料


一. 问题复现

  • 之前操作表的时候,都自认为Mysql的bigint类型对应Java的Long类型。今天写一个查询语句返回Map,结果出现类转换异常。怀疑了好久,查了好半天,终于搞清楚是为什么了。问题现场是这样子滴…

1. mapper.xml

<select id="getInfo" resultType="java.util.Map">
select product_trac_info_id,remark,product_name
from product_trac_info info
where product_trac_info_id=#{productTracInfoId}
select>

2. dao.java

@MapKey("productTracInfoId")
Map<Long,Map<String,String>> getInfo(@Param("productTracInfoId") Long productTracInfoId);

3. manager.java

Map<Long, Map<String, String>> map = infoDao.getInfo(productTracInfoId); 
  • 此时,代码报错,类转换异常,无法将BigInteger转为Long (java.math.BigInteger can’t be cast to java.lang.Long)

二. 问题解答

1. 原因概述

  • 主要原因是数据库字段类型和Java类型不对应导致的。Mysql和Java的对应类型:
Mysql Java
int Integer
int unsigned Long
bigint(20) Long
bigint(20) unsigned BigInteger
  • ⚠️注意
    1. Mysql中有符号int(int) :最大可以支持到约22亿,远远大于我们的需求和MySQL单表所能支持的性能上限。对于OLTP应用来说,单表的规模一般要保持在千万级别,不会达到22亿上限。
    2. Mysql中无符号int(int unsigned) :上限为42亿,这个预留量已经是非常的充足了。如果使用bigint,会占用更大的磁盘和内存空间,内存空间毕竟有限,无效的占用会导致更多的数据换入换出,额外增加了IO的压力,对性能是不利的。

2. 原因解读

  1. 这次的异常就是因为数据库表的product_trac_info_id字段是bigint unsigned类型,导致的类型转换异常。
    在这里插入图片描述
  • BIGINT(20)的取值范围:-9223372036854775808~9223372036854775807,它与Java.lang.Long的取值范围完全一致,因此mybatis会将其映射为Long类型;
  • BIGINT(20) unsigned的取值范围:0 ~ 18446744073709551615,其中一半的数据超出了Long的取值范围,因此Mybatis将其映射为BigInteger类型。
  1. 为什么没有在MyBatis的Dao层或者mapper.xml报错,而是到业务代码里获取Map的时候才报错呢?因为mapper.xml的SQL语句并没有指定Map范型类型,所以map中存储各种类型都可以通过。

参考资料

  • MySQL中BIGINT与Java数据类型对应问题1
  • Mysql的int和bigint字段类型,映射到Java的Integer和Long类型时,勾选UNSIGNED无符号会导致越界转换。
  • MySQL中BIGINT与Java数据类型对应问题2

你可能感兴趣的:(Java)