准备系列-Mybatis(四) TKmybatis-springboot PO类型tinyint转换为Byte/Boolean解决方案

1,055 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

在之前的几篇中,我们已经介绍了项目配置及项目启动,Druid,tkMybatis的配置信息,今天讲一下具体项目中,我们要如何generator 转换生成PO的时候可以正确的生成想要的类型,解决生成类型错误的问题

  • tinyInt在mysql中存储0/1 但是默认的generator生成Byte类型
  • tinyInt在mysql中 对应的PO文件生成了Boolean类型
  • addtime是Long类型,我们如何在mysql中配置使用

1.配置及数据准备

1.1 表结构
CREATE TABLE `user_info` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_id` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户ID',
  `user_name` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户ID',
  `age` int NOT NULL COMMENT '年龄',
  `address` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '地址',
  `order_ids` json DEFAULT NULL COMMENT '用户id的json数组',
  `goods` json DEFAULT NULL COMMENT '用户商品信息 商品对象',
  `sort_order` int DEFAULT '0' COMMENT '排序字段',
  `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
  `is_del2` tinyint NOT NULL COMMENT '测试',
  `addtime` bigint NOT NULL DEFAULT '0' COMMENT '创建时间',
  `modtime` bigint NOT NULL DEFAULT '0' COMMENT '修改时间',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表'

我们注意到 is_del字段及is_del2 配置的是 tinyint ,tinyint(1) 和 tinyint 有什么区别呢?

image.png

1.2 tinyint官方解释

我们看下官方给的配置信息

image.png

  • 如果是tinyInt 1 的情况下, 默认会转化为 java的 boolean类型
  • 如果是tinyInt > 1 的情况下, 默认会转化为Byte

2.实际检验tinyint

2.1 表结构构建好后, 执行generator

我们的 db.properties中配置的URL 是没有任何 tiny转换信息的

!!! 注意 URL 是没有 配置 tinyInt1isBit=true 参数的

## mybatis-generator自动生成代码 !!! 注意 URL 是没有 配置 tinyInt1isBit=true 参数的
#########################################################################################
mybatis.url=jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
mybatis.name=root
mybatis.password=root
datasource.driverClassName=com.mysql.jdbc.Driver
targetModelPackage=com.jzj.tdmybatis.domain.po
targetMapperPackage=sqlmapper
targetClientPackage=com.jzj.tdmybatis.repository.mapper
targetJavaProject=src/main/java
targetResources=src/main/resources

运行 genrator 看看

/**
 * 是否删除
 */
@Column(name = "is_del")
private Boolean isDel;

/**
 * 测试
 */
@Column(name = "is_del2")
private Byte isDel2;
  • is_del 字段的确是Boolean 因为他是tinyint(1)
  • is_del2 字段也是Byte类型,因为当时定义它的是 tinyint(2)但是表结构自动忽略了 长度2,变成了tinyint字段类型

image.png

这明显是不符合 我们要求的, 我们要的是 tinyint长度不管是tinyint(1),tinyint(2), 我们想要的都是Integer 类型

2.2 我们试一试 tinyInt1isBit=true 的配置

db.properties的URL追加配置 &tinyInt1isBit=true 看下效果

mybatis.url=jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&tinyInt1isBit=true

tinyInt1isBit=true 配置为True,执行结果,没有变化,说明 默认就是True

  • is_del tinyint(1)转化为->Boolean
  • is_del2 tinyint 转化为->Byte

image.png

2.3 我们试一试 tinyInt1isBit=false 的配置

db.properties的URL追加配置 &tinyInt1isBit=false 看下效果

mybatis.url=jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&tinyInt1isBit=false

tinyInt1isBit=true 配置为false,执行结果,结果两个全都变成了Byte, tinyint(1)也不转换了

  • is_del tinyint(1)转化为->Byte
  • is_del2 tinyint 转化为->Byte

image.png

上面全都不是我们要的结果,我们其实要的就是 tinyint 转化为Integer 即可,就这么简单,该如何实现 ?

3.解决办法一 每个表结构单独处理

每个表结构生成的时候,对字段做单独处理,指定字段类型 比如 表table user_info, 字段 is_del, is_del2 指定类型,在generatorConfig.xml中配置

缺点是每个表 你都需要单独配置字段信息,不通用 generatorConfig.xml配置

<table tableName="user_info" domainObjectName="UserInfoPO"
       mapperName="UserInfoMapper">
    <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
    <columnOverride column="is_del" property="isDel" javaType="java.lang.Integer"/>
    <columnOverride column="is_del2" property="isDel2" javaType="java.lang.Integer"/>
</table>

配置完成后,再次运行 generator,可以看到结果,结果两个全都变成了Integer,是我们想要的

  • is_del tinyint(1)转化为->Integer
  • is_del2 tinyint 转化为->Integer

image.png

4.通用解决办法 配置 javaTypeResolver

在配置文件中有一个 <javaTypeResolver> 标签可以用来配置映射关系,字段与Java的映射关系在构造方法中配置。

新建类继承 JavaTypeResolverDefaultImpl ,在子类构造方法中重新对 typeMap 赋值,利用 HashMap<> key相同value替换的性质替换默认的实现方式

下一篇我们 讲 通用配置方法如何 解决这种问题