Mybatis Generator将tinyint映射成Integer的解决办法

环境

Java:1.8+
mybatis:3.3.0
mybatis-generator-core:1.3.5

前言

今天遇到了这么一个错误:

TicketMonitorServiceImpl.personMonitorPage.error org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'TINYINT'.  Cause: java.lang.ClassNotFoundException: Cannot find class: TINYINT
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:368)
	at com.sun.proxy.$Proxy104.selectList(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:198)
	at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:122)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:64)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
	at com.sun.proxy.$Proxy181.selectPartUserIdByQO(Unknown Source)

也就是说,不能识别或者找到TINYINT; 我的dao层代码是用生成工具生成出来的;
字段 is_accept java类型是Byte, jdbcType类型是TINYINT;
刚开始,我以为是不能使用jdbcType:TINYINT,javaType:Byte这套组合.所以就想着换成Integer类型。
实际上,之所以报错的原因是:其实是我在XXXMapper.xml文件中写错了类型:

# 错误的写法
is_accept = #{accept,javaType=TINYINT}
# 正确应该是
is_accept = #{accept,jdbcType=TINYINT}

不过,既然遇到了,所以就顺道研究了下:1. tinyint如何转Integer的问题?2. tinyint(1)为什么又会转为Boolean?

将tinyint映射成Integer

先来看看MySQL的官方文档:

Java, JDBC and MySQL Types

下面这张图,是说,MySQL的数据类型,可能转为Java的类型有哪些~
在这里插入图片描述
这张图,是明细图,就明确的告诉你,MySQL的数据类型,一定会传为Java的哪个类型~
在这里插入图片描述
我们看到标红的地方,翻译过来就是:当字符类型为tinyint且长度为 1 时,会被转换成布尔类型。如果tinyInt1isBit取false时,则转Integer。

实际你会发现,即使设置了tinyInt1isBit=false,依然不会转Integer;
其实是因为mybatis,在tinyint(1)的情况下,映射成BIT
即:<result column="deleted" property="deleted" jdbcType="BIT" />
因为映射成了BIT类型,所以使用tinyInt1isBit=false参数当然不会起作用。
解法,看后面的tinyint(1) mybatis会生成jdbcType=BIT,导致转Integer失败的解法

解决tinyint转Integer的方法有两种:

方法一:继承插件接口JavaTypeResolverDefaultImpl

mybatis官方文档
在这里插入图片描述
在配置文件中有一个 <javaTypeResolver> 标签可以用来配置映射关系。而该标签有一个 type 属性。上图中的英文翻译过来就是:用户可以提供一个自定义的实现,该类必须实现JavaTypeResolver接口,且必须有一个共有的默认构造器,或者沿用默认值DEFAULT,将使用JavaTypeResolverDefaultImpl来进行映射;

package com.sgy;

import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;

import java.sql.Types;

public class TinyIntJavaTypeResolver extends JavaTypeResolverDefaultImpl {

    public TinyIntJavaTypeResolver() {
        super();
        typeMap.put(Types.TINYINT, new JavaTypeResolverDefaultImpl
                .JdbcTypeInformation("TINYINT", new FullyQualifiedJavaType(Integer.class.getName())));

    }
}

因为我们实际项目开发中,使用的generator是以Maven插件的形式集成到项目中的,插件启动的时候并不会加载我项目中的类文件。故会报类无法加载的错误。解决方法就是将该类的依赖,添加到插件的依赖中。

pom.xml文件中,添加模块依赖。

<plugin>
	<groupId>org.mybatis.generator</groupId>
	<artifactId>mybatis-generator-maven-plugin</artifactId>
	<version>1.3.2</version>
	<dependencies>
	    <!--重点这里,将类所在的模块,引入进来,因为是本项目,所以排除掉全部的传递依赖-->
	    <!--重点这里,因为我的类TinyIntJavaTypeResolver写在server层,所以只添加server的依赖-->
	    <!--重点这里,即:yutao-server-->
		<dependency>
			<groupId>com.sgy</groupId>
			<artifactId>yutao-server</artifactId>
			<version>1.0.1-SNAPSHOT</version>
			<exclusions>
				<exclusion>
					<groupId>*</groupId>
					<artifactId>*</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>
	<configuration>
		<verbose>true</verbose>
		<overwrite>true</overwrite>
		<configurationFile>${basedir}/src/main/resources/mybatis_generator/generatorConfig-yt.xml
		</configurationFile>
	</configuration>
</plugin>

接着在generatorConfig.xml文件中:

... ...
<!-- 数据库链接URL、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/misstest"
                userId="root" password="rootroot">
</jdbcConnection>
<javaTypeResolver type="me.ele.bi.woos.utils.TinyIntJavaTypeResolver">
    <property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
... ...

自此,完毕,现在生成的代码就是可以将 tinyint映射成Integer的。

但是这种方式,对于tinyint(1)的情况是不行的,因为tinyint(1)的情况,在mybatis中,jdbcType被映射成了BIT类型,这里我们有两种改法:

tinyint(1) mybatis会生成jdbcType=BIT,导致转Integer失败的解法

①改法一:

public TinyIntJavaTypeResolver() {
   super();
   typeMap.put(Types.TINYINT, new JavaTypeResolverDefaultImpl
           .JdbcTypeInformation("TINYINT", new FullyQualifiedJavaType(Integer.class.getName())));
   //加一段bit的映射
   typeMap.put(Types.BIT, new JavaTypeResolverDefaultImpl
           .JdbcTypeInformation("BIT", new FullyQualifiedJavaType(Integer.class.getName())));
}

加一段bit的映射就可以了。

②改法二:

不设置tinyint(1),等于就是叫你别这样用了。或者考虑使用下面的方法二

方法二:在配置文件generatorConfig.xml中直接指定

这个就简单很多了

<table tableName="test" domainObjectName="Test" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
    <columnOverride column="deleted" property="deleted" javaType="java.lang.Integer" />
    <columnOverride column="is_accept" property="isAccept" javaType="java.lang.Integer" />
</table>

重点要注意:是javaType="java.lang.Integer",即:javaType,不是配置jdbcType,两者千万别搞混了。

然后我们测试,生成文件看看:

生成的Mapper.xml:
在这里插入图片描述
生成的model是:

在这里插入图片描述

这样也就OK了。

总结

我们学到了,有两种方法可以将 tinyint 映射为 Integer。

方法一,继承JavaTypeResolverDefaultImpl接口的方式,比较通用。

方法二,在配置文件generatorConfig.xml中直接指定,这种方式简单,粗暴;只不过每次生成一张表,都需要进行配置(假设需要的话)。

最后,我最开始报错的原因,其实是我在XXXMapper.xml文件中写错了类型:

is_accept = #{accept,javaType=TINYINT}
# 正确应该是
is_accept = #{accept,jdbcType=TINYINT}

假设最开始我写对了,其实Java类型使用Byte,是没有问题的。

价值参考

5.5 Java, JDBC and MySQL Types

解决tinyint映射成boolean/byte的问题

解决Mybatis generatorConfig.xml将tinyint映射为Byte和Boolean

https://blog.csdn.net/yu542771572/article/details/116607642

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在使用Mybatis Generator代码时,默认情况下,MySQL数据库中的tinyint类型会映射Java的Boolean类型。然而,有一些情况下我们可能需要将tinyint映射Java的Byte类型。为了实现这个映射,可以使用自定义的类型解析器。在自定义类型解析器中,我们可以将数据库的TINYINT映射JavaInteger类型。具体的做法是,在自定义的JavaTypeResolver中添加如下代码: ```java public class CustomerJavaTypeResolver extends JavaTypeResolverDefaultImpl { public CustomerJavaTypeResolver() { super(); //将数据库的TINYINT映射Integer类型 super.typeMap.put(Types.TINYINT, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TINYINT", new FullyQualifiedJavaType(Integer.class.getName()))); } } ``` 通过这种方式,我们可以将MySQL中的tinyint类型映射JavaInteger类型。这样,在使用Mybatis Generator代码时,tinyint字段就会被映射JavaInteger类型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Mybaits-mybatis-generator数据库tinyint数据类型类型映射问题](https://blog.csdn.net/qq_19331985/article/details/104790644)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [解决Mybatis Generatortinyint映射为Byte和Boolean](https://blog.csdn.net/yu542771572/article/details/116607642)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山鬼谣me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值