springboot 2.3.0+activeRecord获取对象报类型转换错误

场景:

  1. 业务表里有一个字段is_delete,Model自动生成后该字段是一个布尔类型: `is_delete` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否删除:1,是;0,否'

  2. 框架使用的是springboot + activeRecord

  3. spring-boot-starter-parent使用低版本如2.1.3.RELEASE,使用dao.findFirst时候一切正常,返回的对象中is_delete是布尔型

  4. 下面问题来了,当spring-boot-starter-parent使用高版本如2.3.0.RELEASE的时候,问题出现了。返回的对象中is_delete是数字0,不是布尔型,导致类型转换报错。


尝试解决:

经过调试发现com.jfinal.plugin.activerecord.generator.MetaBuilder类中以下地方有差别

if (typeStr == null) {
    String colClassName = rsmd.getColumnClassName(i);
    typeStr = typeMapping.getType(colClassName);
}

对于colClassName,低版本的springboot环境中获取到的是java.lang.Boolean,高版本是java.lang.Integer。

对于rsmd对象进行打印后,

低版本中是这样:com.mysql.cj.result.Field@53499d85[catalog=jtxxh,tableName=sys_department,originalTableName=sys_department,columnName=is_delete,originalColumnName=is_delete,mysqlType=1(FIELD_TYPE_BIT),sqlType=-7,flags= UNSIGNED, charsetIndex=63, charsetName=ISO-8859-1]

高版本中是这样:com.mysql.cj.result.Field@780ec4a5[dbName=jtxxh,tableName=sys_department,originalTableName=sys_department,columnName=is_delete,originalColumnName=is_delete,mysqlType=1(FIELD_TYPE_TINYINT UNSIGNED),sqlType=-6,flags= UNSIGNED, charsetIndex=63, charsetName=ISO-8859-1]

从上面的打印看,高版本环境下对于mysqlType的判断更加准确,是什么导致的呢?嘿嘿,经过仔细分析和观察,mysql驱动版本不一样。高版本的springboot自带的是8.0.20,而低版本自带的是8.0.15。

之前对于mysql驱动的引入是这么写的:

<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
</dependency>

他的版本号由springboot的版本号决定。所以如果要解决上述问题,就是让is_delete字段保持之前的布尔型,只要显式的指定mysql版本号即可。

评论区

JFinal

2020-06-04 20:40

这个描述,看上去是 spring boot 的版本变化造成的,建议你用一下排除法解决一下

对于变化的部分,一项项排除

在 jfinal 层面,jfinal 是没有干预这个结果的

我一般是建议不要使用 tinyint(1) 而是使用 tinyint(2) 等等长度大于 1 的类型,这样的结果更确定,一定会是 int 型

happyboy

2020-06-04 20:47

@JFinal tinyint(1) 会转变成布尔型是无意中发现的,起初还不适应,后来发现也挺方便的。如果一定要用准确的类型,我们一般习惯用char(1),不想浪费一点空间,O(∩_∩)O哈哈~ 这个问题我再想办法排查下。

chcode

2020-06-05 09:58

@happyboy 我和你一样咋没问题,还是布尔类型

happyboy

2020-06-05 18:07

@chcode 这么神奇吗?springboot 也是2.3.0?

happyboy

2020-06-08 15:31

@JFinal 波总,找到原因了,其实压根就跟springboot没关系,是升级了activeRecord的原因,升级到4.9之后,重新生成model,is_delete字段已经不是之前的布尔型,而是Integer类型。有啥办法能操持之前的布尔模式吗?

JFinal

2020-06-08 15:47

@happyboy 这个应变也不是 4.9 的原因,你试着用回 4.8 , 看看生成的结果如何

因为 4.9 压根没动过这个地方

happyboy

2020-06-08 16:33

@JFinal 我是从4.3升级上来的,4.3就是布尔型。

JFinal

2020-06-08 17:17

@happyboy 你改回 4.3 ,再生成一下试试

happyboy

2020-06-08 21:40

@JFinal 已找到原因,正文已做补充和说明。感谢波总,^_^

JFinal

2020-06-09 00:19

@happyboy 寻根问底的精神,赞