前言

最近受疫情的影响,公司要做一个类似一码通的系统为客户服务。由我来进行表的设计。创建表之后需要逆向生成Java的entity、mapper、mapper.xml。由于我在数据库中定义了大量 tinyint(1) 的字段。在逆向的时候,默认生成的是Boolean类型的变量。而我们习惯于使用 Integer 作为tinyint的Java类型,这要怎么转换呢?因此这里就有两个问题需要解决:

  1. tinyint(1) 转换成数字类型而不是布尔类型
  2. tinyint(n) n>1 转换成 Integer 而非 Byte

tinyint(1) 转换成数字类型

在数据库连接url后面加上参数(建议复制,大小写错了不生效。多个keyvalue之间用 & 连接):

  1. tinyInt1isBit=false

这一点在官方文档有说明:

翻译过来就是:当字符类型为tinyint且长度为 1 时,会被转换成布尔类型。而虽然文档上说tinyInt1isBit取false时,转Integer。实际上转过来还是 Byte

tinyint(n) n>1 转换成 Integer

MyBatis Generator 是通过JavaTypeResolver 来实现关系映射的,官方文档解释

在配置文件中有一个 <javaTypeResolver> 标签可以用来配置映射关系。而该标签有一个 type 属性。红色字体翻译过来就是:用户可以提供一个自定义的实现,该类必须实现JavaTypeResolver接口,且必须有一个共有的默认构造器,或者沿用默认值DEFAULT,将使用JavaTypeResolverDefaultImpl来进行映射,首先我们看一看它默认的实现类的构造方法

  1. public JavaTypeResolverDefaultImpl() {
  2. super();
  3. properties = new Properties();
  4. typeMap = new HashMap<>();
  5. // 此处省略其他字段的映射......
  6. typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT", //$NON-NLS-1$
  7. new FullyQualifiedJavaType(Byte.class.getName())));
  8. }

很明显,字段与Java的映射关系在构造方法中配置。我们改起来很简单,新建类继承 JavaTypeResolverDefaultImpl ,在子类构造方法中重新对 typeMap 赋值,利用 HashMap<> key相同value替换的性质替换默认的实现方式

  1. package other;
  2. import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
  3. import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
  4. import java.sql.Types;
  5. public class MyTypeResolver extends JavaTypeResolverDefaultImpl {
  6. public MyTypeResolver() {
  7. super();
  8. typeMap.put(Types.TINYINT, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TINYINT", //$NON-NLS-1$
  9. new FullyQualifiedJavaType(Integer.class.getName())));
  10. }
  11. }

做完这些,将该类路径写在 type 中运行,你会发现该类无法被加载......

打包类文件,被generator所依赖

因为我所使用的generator是以Maven插件的形式集成到项目中的,插件启动的时候并不会加载我项目中的类文件。故会报类无法加载的错误。解决方法就是将该类文件打包,然后添加到插件的依赖中。如果你所在的公司项目中有公共的工具类项目可以直接在项目中写,上传到私服。如果没有,按照以下的步骤进行:

  1. 创建新项目,配好本地仓库地址
  2. 添加和你generator插件版本一样的generator依赖
  3. 新建类
  4. install

这时你的工具类就已经发布到本地仓库了。此时在原来的插件中依赖该项目,并且排除generator的依赖。就可以正常生成Integer了:

  1. <plugin>
  2. <groupId>org.mybatis.generator</groupId>
  3. <artifactId>mybatis-generator-maven-plugin</artifactId>
  4. <dependencies>
  5. <dependency>
  6. <groupId>mysql</groupId>
  7. <artifactId>mysql-connector-java</artifactId>
  8. <version>5.1.27</version>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.mybatis.generator</groupId>
  12. <artifactId>mybatis-generator-core</artifactId>
  13. <version>1.4.0</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>com.woke</groupId>
  17. <artifactId>common</artifactId>
  18. <version>1.0-SNAPSHOT</version>
  19. <exclusions>
  20. <exclusion>
  21. <groupId>org.mybatis.generator</groupId>
  22. <artifactId>mybatis-generator-core</artifactId>
  23. </exclusion>
  24. </exclusions>
  25. </dependency>
  26. </dependencies>
  27. <executions>
  28. <execution>
  29. <id>Generate MyBatis Artifacts</id>
  30. <phase>package</phase>
  31. <goals>
  32. <goal>generate</goal>
  33. </goals>
  34. </execution>
  35. </executions>
  36. <configuration>
  37. <!-- 允许移动生成的文件 -->
  38. <verbose>true</verbose>
  39. <!-- 是否覆盖 -->
  40. <overwrite>false</overwrite>
  41. <!-- 自动生成的配置 -->
  42. <configurationFile>
  43. src/main/resources/mybatis-generator.xml</configurationFile>
  44. </configuration>
  45. </plugin>

generator配置

mybatis-generator.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE generatorConfiguration
  3. PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  4. "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
  5. <generatorConfiguration>
  6. <!--mysql 连接数据库jar 这里选择自己本地位置-->
  7. <classPathEntry
  8. location="D:\Application\apache-maven-3.3.9\localRepository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar"/>
  9. <context id="testTables" targetRuntime="MyBatis3">
  10. <commentGenerator>
  11. <!-- 是否去除自动生成的注释 true:是 : false:否 -->
  12. <property name="suppressAllComments" value="true"/>
  13. </commentGenerator>
  14. <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
  15. <jdbcConnection driverClass="com.mysql.jdbc.Driver"
  16. connectionURL="jdbc:mysql://localhost:3306/woke_cloud_property?serverTimezone=UTC&amp;tinyInt1isBit=false"
  17. userId="root"
  18. password="root">
  19. </jdbcConnection>
  20. <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
  21. NUMERIC 类型解析为java.math.BigDecimal -->
  22. <javaTypeResolver type="other.MyTypeResolver">
  23. <property name="forceBigDecimals" value="false"/>
  24. </javaTypeResolver>
  25. <!-- targetProject:生成PO类的位置 -->
  26. <javaModelGenerator targetPackage="cn.keats.project.camp.entity"
  27. targetProject="src/main/java">
  28. <!-- enableSubPackages:是否让schema作为包的后缀 -->
  29. <property name="enableSubPackages" value="false"/>
  30. <!-- 从数据库返回的值被清理前后的空格 -->
  31. <property name="trimStrings" value="true"/>
  32. </javaModelGenerator>
  33. <!-- targetProject:mapper映射文件生成的位置
  34. 如果maven工程只是单独的一个工程,targetProject="src/main/java"
  35. 若果maven工程是分模块的工程,targetProject="所属模块的名称",例如:
  36. targetProject="ecps-manager-mapper",下同-->
  37. <sqlMapGenerator targetPackage="mapper"
  38. targetProject="src/main/resources">
  39. <!-- enableSubPackages:是否让schema作为包的后缀 -->
  40. <property name="enableSubPackages" value="false"/>
  41. </sqlMapGenerator>
  42. <!-- targetPackage:mapper接口生成的位置 -->
  43. <javaClientGenerator type="XMLMAPPER"
  44. targetPackage="cn.keats.project.camp.mapper"
  45. targetProject="src/main/java">
  46. <!-- enableSubPackages:是否让schema作为包的后缀 -->
  47. <property name="enableSubPackages" value="false"/>
  48. </javaClientGenerator>
  49. <!-- 指定数据库表 多个表示,可用多个table标签-->
  50. <table tableName="test_tinyint"
  51. enableCountByExample="false"
  52. enableUpdateByExample="false"
  53. enableDeleteByExample="false"
  54. enableSelectByExample="false"
  55. selectByExampleQueryId="false">
  56. </table>
  57. </context>
  58. </generatorConfiguration>

其他逆向工程的工具

easycode通过IDEA连接数据库后,可以使用右键直接生成,高度定制化

mybaits plus 设置起来和 generator 差不多,不过方便的是可以在main方法直接设置:

  1. // 重写Mysql关于字段类型的转换配置
  2. dsc.setTypeConvert((globalConfig, fieldType) -> {
  3. String t = fieldType.toLowerCase();
  4. if (t.contains("char")) {
  5. return DbColumnType.STRING;
  6. } else if (t.contains("bigint")) {
  7. return DbColumnType.LONG;
  8. } else if (t.contains("tinyint(1)")) {
  9. return DbColumnType.INTEGER;
  10. } else if (t.contains("int")) {
  11. return DbColumnType.INTEGER;
  12. } else if (t.contains("text")) {
  13. return DbColumnType.STRING;
  14. } else if (t.contains("bit")) {
  15. return DbColumnType.BOOLEAN;
  16. } else if (t.contains("decimal")) {
  17. return DbColumnType.BIG_DECIMAL;
  18. } else if (t.contains("clob")) {
  19. return DbColumnType.CLOB;
  20. } else if (t.contains("blob")) {
  21. return DbColumnType.BLOB;
  22. } else if (t.contains("binary")) {
  23. return DbColumnType.BYTE_ARRAY;
  24. } else if (t.contains("float")) {
  25. return DbColumnType.FLOAT;
  26. } else if (t.contains("double")) {
  27. return DbColumnType.DOUBLE;
  28. } else if (t.contains("json") || t.contains("enum")) {
  29. return DbColumnType.STRING;
  30. } else if (t.contains("date") || t.contains("time") || t.contains("year")) {
  31. switch (globalConfig.getDateType()) {
  32. case ONLY_DATE:
  33. return DbColumnType.DATE;
  34. case SQL_PACK:
  35. switch (t) {
  36. case "date":
  37. return DbColumnType.DATE_SQL;
  38. case "time":
  39. return DbColumnType.TIME;
  40. case "year":
  41. return DbColumnType.DATE_SQL;
  42. default:
  43. return DbColumnType.TIMESTAMP;
  44. }
  45. case TIME_PACK:
  46. switch (t) {
  47. case "date":
  48. return DbColumnType.LOCAL_DATE;
  49. case "time":
  50. return DbColumnType.LOCAL_TIME;
  51. case "year":
  52. return DbColumnType.YEAR;
  53. default:
  54. return DbColumnType.LOCAL_DATE_TIME;
  55. }
  56. }
  57. }
  58. return DbColumnType.STRING;
  59. });
  60. mpg.setDataSource(dsc);

解决tinyint映射成boolean/byte的问题的更多相关文章

  1. Mybaits 源码解析 (八)----- 全网最详细,没有之一:结果集 ResultSet 自动映射成实体类对象(上篇)

    上一篇文章我们已经将SQL发送到了数据库,并返回了ResultSet,接下来就是将结果集 ResultSet 自动映射成实体类对象.这样使用者就无需再手动操作结果集,并将数据填充到实体类对象中.这可大 ...

  2. nand烧写分析/内核在启动过程中式如何将这个文件映射成/目录及各子目录的?

    我用的是ramdisk.image.gz,烧写在flash的0x10140000处 我不太明白内核在启动过程中式如何将这个文件映射成/目录及各子目录的? 如果ramdisk.image.gz在flas ...

  3. bitMap算法实现以及ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串

    ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串 说明 1.所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来 ...

  4. 对于Oracle中Number类型的字段映射成Java中的具体类型的问题

    我在Oracle中给一个用户Id字段设置为Number类型,使用JDBC在完成ORM的时候,以为其可以自动转换为Integer,因为我的POJO类id使用的就是Integer.但事实是,我在测试的时候 ...

  5. 怎么让Intellj Idea 把数据库的表映射成hibernate的domain对象

    步骤如下: 第一步:连接数据源: 点击:idea右边的database.如下图所示: 或者你依次点击:view-->Tool windows--->database 然后你将看在如下点击下 ...

  6. 微信公众号开发之怎样将本机IP映射成外网域名

    近期一个项目须要用到微信公众号的网页授权登录,在研究这个公众号的时候遇到各种困难,现将自己的一些心得总结一下. 我想进行微信公众号开发遇到的第一个困难就是微信公众号必须输入一个外网能够訪问的域名,在网 ...

  7. Ceph 块存储 创建的image 映射成块设备

    将创建的volume1映射成块设备 [root@mysql-server ceph]# rbd map rbd_pool/volume1 rbd: sysfs write failed RBD ima ...

  8. mybatis枚举映射成tinyint

    第一步:定义顶级枚举接口 public interface BaseEnum<E extends Enum<?>, T> { public T getCode(); publi ...

  9. Mybatis 查询tinyint(1)的数据库字段时会自动转换成boolean类型

    解决方案:将字段的tinyint(1)变成tinyint(2)

随机推荐

  1. if分支判断

    # 控制语句 分支 循环语句 # 判断语句 if ..elif..else # if 条件语句(比较 逻辑 成员运算) # 空数据 == False # 非空数据 == True age = 20 i ...

  2. 吴裕雄--天生自然KITTEN编程:滂沱大雨

  3. Python---6条件判断与循环

    条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age >= ...

  4. windowserver 2012安装openssh

    下载https://github.com/PowerShell/Win32-OpenSSH/releases解压放到C:\Program Files\OpenSSH-Win64 进入到C:\Progr ...

  5. 谈谈Vue的递归组件

    2月最后一天,而且还四年一遇,然而本月居然一篇博客没写,有点说不过去.所以,今天就来谈谈Vue的递归组件.我们先来看一个例子: See the Pen 递归组件 by imgss (@imgss) o ...

  6. Logstash实践

    转载请注明出处:https://www.cnblogs.com/shining5/p/9542710.html Logstash简介 一个开源的数据收集引擎,具有实时数据传输能力,可以统一过滤来自不同 ...

  7. 先搞清楚这些问题,简历上再写你熟悉Java!

    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 系列文章介绍 本文是<五分钟学Java>系列文章的一篇 本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年 ...

  8. Python开发(一):Python介绍与基础知识

    Python开发(一):Python介绍与基础知识 本次内容 一:Python介绍: 二:Python是一门什么语言 三:Python:安装 四:第一个程序 “Hello world” 五:Pytho ...

  9. Docker Compose 项目打包部署

    Docker Compose 前面我们使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker build.docker run 等命令操作容器.然而微服务架构的应用系统一 ...

  10. 统计 Django 项目的测试覆盖率

    作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 我们完成了对 blog 应用和 comment 应用这两个核心 app 的测试.现在 ...