场景:
业务表里有一个字段is_delete,Model自动生成后该字段是一个布尔类型: `is_delete` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否删除:1,是;0,否'
框架使用的是springboot + activeRecord
spring-boot-starter-parent使用低版本如2.1.3.RELEASE,使用dao.findFirst时候一切正常,返回的对象中is_delete是布尔型
下面问题来了,当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 层面,jfinal 是没有干预这个结果的
我一般是建议不要使用 tinyint(1) 而是使用 tinyint(2) 等等长度大于 1 的类型,这样的结果更确定,一定会是 int 型