mysql中的bigint类型竟变成了它?

点击上方名片关注我,为你带来更多踩坑案例

85eb93a462413f4905407582183ec73a.png

引导

8914f0e8638f67855221b6647f61706a.gif

废话不多说,本文从现象-解决办法-原因三个方面来简述

解决办法有多种,大家根据自己的情况自行选择

现象

243b4c030f4b674c32988d8252bd86ec.gif

mysql中的字段是bigint(20)类型,java中实体类的字段是Long类型,写了一个方法大概如下:

@Query(value = "select id from test_people where status = 1", nativeQuery = true)
 List<Long> findId();

然后得到一个List<id> ids,取ids中元素的时候报错

java.math.BigInteger cannot be cast to java.lang.Long

想必很多朋友经常碰到这个问题,下面说解决办法

解决办法1-JPQL

c8067012624c1da25164f79f89a612c9.gif

这个办法最快捷,直接使用JPQL语句替代原生sql,这样返回的值就是Long啦。

@Query(value = "select id from People where status = 1")
List<Long> findId();

解决办法2-替换jdbc版本

1cabcf8345c0d4858b6706465bf538d7.gif

替换jdbc的版本,比如我的版本一开始是

9821da5ad560e6703dbaa18927c0d987.png

替换为了

d8a972d5243eec81a25e18d07115694e.png

我是和springcloud整体做了一个升级,小伙伴们也可以单独升级jdbc及其相关依赖。

d0c5d36c327b936befddfa7577e7f4ed.png

<version>2.2.6.RELEASE</version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>

关于改到哪个版本,可以具体参考springcloud的兼容性,结合自己项目的实际情况来决定或尝试。

springcloud的版本兼容性

ps:替换之后确保重新下好了依赖并且重新打包

解决办法3-应用层转换

3b786906e34e030626c863909a4b4bed.gif

这个方法也比较简单,包括但不限于在应用层中把BigInteger转为String,String再转为Long,以及搞一些自定义类的方法。

我本人是不太推荐这种办法的,有点自欺欺人,但紧急情况下也不失为一种解决办法。

解决办法4-修改接收类

399c28fcdb427b4be2d05aad345762ab.gif

既然BigInteger转不成Long类型,那就不转了呗,数据库bigint字段的值,直接统一用BigInteger接收就好了。

这种方法比较适用于新项目。

原因

b8bcd420b6b54accd476737d84c4b648.gif

究其原因,就是某些版本的jdbc把数据库中的bigint类型映射成了BigInteger类型,而不是预期的Long类型。

可能有朋友会疑惑,bigint是8个字节,Long也是8个字节,有的版本也的确是bigint->Long,为什么要转成BigInteger呢?

那是因为bigint可以是无符号整数,Long是有符号的,当bigint是无符号整数时,二者可表达的最大值就差了一倍了,用Long接的话可能会溢出

所以有些版本直接转成BigInteger

小附录

a61b2d9aebfb57b80e9c0a566c8c5cd6.gif

可能有些朋友会注意到一个问题,那就是sql的返回值接收参数的时候

List<Long> id1 = projectRepository.findId();
Long aLong = id1.get(0);

也就是第一行并不会报错

但是在第二行取用的时候会报错,这又是为什么?

那是因为java中的泛型仅在编译器生效检查,存在泛型擦除机制,所以导致了牛头接马面的现象,然后直到真正使用的时候才露馅。

大家感兴趣的可以去了解下泛型擦除机制。

猜你喜欢

转载自blog.csdn.net/qq_31363843/article/details/129385268
今日推荐