解决tinyint映射成boolean/byte的问题
前言
最近受疫情的影响,公司要做一个类似一码通的系统为客户服务。由我来进行表的设计。创建表之后需要逆向生成Java的entity、mapper、mapper.xml。由于我在数据库中定义了大量 tinyint(1) 的字段。在逆向的时候,默认生成的是Boolean类型的变量。而我们习惯于使用 Integer 作为tinyint的Java类型,这要怎么转换呢?因此这里就有两个问题需要解决:
- tinyint(1) 转换成数字类型而不是布尔类型
- tinyint(n) n>1 转换成 Integer 而非 Byte
tinyint(1) 转换成数字类型
在数据库连接url后面加上参数(建议复制,大小写错了不生效。多个keyvalue之间用 & 连接):
tinyInt1isBit=false
这一点在官方文档有说明:
翻译过来就是:当字符类型为tinyint且长度为 1 时,会被转换成布尔类型。而虽然文档上说tinyInt1isBit取false时,转Integer。实际上转过来还是 Byte
tinyint(n) n>1 转换成 Integer
MyBatis Generator 是通过JavaTypeResolver 来实现关系映射的,官方文档解释
在配置文件中有一个 <javaTypeResolver>
标签可以用来配置映射关系。而该标签有一个 type 属性。红色字体翻译过来就是:用户可以提供一个自定义的实现,该类必须实现JavaTypeResolver接口,且必须有一个共有的默认构造器,或者沿用默认值DEFAULT,将使用JavaTypeResolverDefaultImpl来进行映射,首先我们看一看它默认的实现类的构造方法
public JavaTypeResolverDefaultImpl() {
super();
properties = new Properties();
typeMap = new HashMap<>();
// 此处省略其他字段的映射......
typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT", //$NON-NLS-1$
new FullyQualifiedJavaType(Byte.class.getName())));
}
很明显,字段与Java的映射关系在构造方法中配置。我们改起来很简单,新建类继承 JavaTypeResolverDefaultImpl ,在子类构造方法中重新对 typeMap 赋值,利用 HashMap<> key相同value替换的性质替换默认的实现方式
package other;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
import java.sql.Types;
public class MyTypeResolver extends JavaTypeResolverDefaultImpl {
public MyTypeResolver() {
super();
typeMap.put(Types.TINYINT, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TINYINT", //$NON-NLS-1$
new FullyQualifiedJavaType(Integer.class.getName())));
}
}
做完这些,将该类路径写在 type 中运行,你会发现该类无法被加载......
打包类文件,被generator所依赖
因为我所使用的generator是以Maven插件的形式集成到项目中的,插件启动的时候并不会加载我项目中的类文件。故会报类无法加载的错误。解决方法就是将该类文件打包,然后添加到插件的依赖中。如果你所在的公司项目中有公共的工具类项目可以直接在项目中写,上传到私服。如果没有,按照以下的步骤进行:
- 创建新项目,配好本地仓库地址
- 添加和你generator插件版本一样的generator依赖
- 新建类
- install
这时你的工具类就已经发布到本地仓库了。此时在原来的插件中依赖该项目,并且排除generator的依赖。就可以正常生成Integer了:
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.27</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.woke</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<phase>package</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 允许移动生成的文件 -->
<verbose>true</verbose>
<!-- 是否覆盖 -->
<overwrite>false</overwrite>
<!-- 自动生成的配置 -->
<configurationFile>
src/main/resources/mybatis-generator.xml</configurationFile>
</configuration>
</plugin>
generator配置
mybatis-generator.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--mysql 连接数据库jar 这里选择自己本地位置-->
<classPathEntry
location="D:\Application\apache-maven-3.3.9\localRepository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar"/>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/woke_cloud_property?serverTimezone=UTC&tinyInt1isBit=false"
userId="root"
password="root">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver type="other.MyTypeResolver">
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="cn.keats.project.camp.entity"
targetProject="src/main/java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置
如果maven工程只是单独的一个工程,targetProject="src/main/java"
若果maven工程是分模块的工程,targetProject="所属模块的名称",例如:
targetProject="ecps-manager-mapper",下同-->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="cn.keats.project.camp.mapper"
targetProject="src/main/java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 指定数据库表 多个表示,可用多个table标签-->
<table tableName="test_tinyint"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>
其他逆向工程的工具
easycode通过IDEA连接数据库后,可以使用右键直接生成,高度定制化
mybaits plus 设置起来和 generator 差不多,不过方便的是可以在main方法直接设置:
// 重写Mysql关于字段类型的转换配置
dsc.setTypeConvert((globalConfig, fieldType) -> {
String t = fieldType.toLowerCase();
if (t.contains("char")) {
return DbColumnType.STRING;
} else if (t.contains("bigint")) {
return DbColumnType.LONG;
} else if (t.contains("tinyint(1)")) {
return DbColumnType.INTEGER;
} else if (t.contains("int")) {
return DbColumnType.INTEGER;
} else if (t.contains("text")) {
return DbColumnType.STRING;
} else if (t.contains("bit")) {
return DbColumnType.BOOLEAN;
} else if (t.contains("decimal")) {
return DbColumnType.BIG_DECIMAL;
} else if (t.contains("clob")) {
return DbColumnType.CLOB;
} else if (t.contains("blob")) {
return DbColumnType.BLOB;
} else if (t.contains("binary")) {
return DbColumnType.BYTE_ARRAY;
} else if (t.contains("float")) {
return DbColumnType.FLOAT;
} else if (t.contains("double")) {
return DbColumnType.DOUBLE;
} else if (t.contains("json") || t.contains("enum")) {
return DbColumnType.STRING;
} else if (t.contains("date") || t.contains("time") || t.contains("year")) {
switch (globalConfig.getDateType()) {
case ONLY_DATE:
return DbColumnType.DATE;
case SQL_PACK:
switch (t) {
case "date":
return DbColumnType.DATE_SQL;
case "time":
return DbColumnType.TIME;
case "year":
return DbColumnType.DATE_SQL;
default:
return DbColumnType.TIMESTAMP;
}
case TIME_PACK:
switch (t) {
case "date":
return DbColumnType.LOCAL_DATE;
case "time":
return DbColumnType.LOCAL_TIME;
case "year":
return DbColumnType.YEAR;
default:
return DbColumnType.LOCAL_DATE_TIME;
}
}
}
return DbColumnType.STRING;
});
mpg.setDataSource(dsc);
解决tinyint映射成boolean/byte的问题的更多相关文章
- Mybaits 源码解析 (八)----- 全网最详细,没有之一:结果集 ResultSet 自动映射成实体类对象(上篇)
上一篇文章我们已经将SQL发送到了数据库,并返回了ResultSet,接下来就是将结果集 ResultSet 自动映射成实体类对象.这样使用者就无需再手动操作结果集,并将数据填充到实体类对象中.这可大 ...
- nand烧写分析/内核在启动过程中式如何将这个文件映射成/目录及各子目录的?
我用的是ramdisk.image.gz,烧写在flash的0x10140000处 我不太明白内核在启动过程中式如何将这个文件映射成/目录及各子目录的? 如果ramdisk.image.gz在flas ...
- bitMap算法实现以及ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串
ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串 说明 1.所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来 ...
- 对于Oracle中Number类型的字段映射成Java中的具体类型的问题
我在Oracle中给一个用户Id字段设置为Number类型,使用JDBC在完成ORM的时候,以为其可以自动转换为Integer,因为我的POJO类id使用的就是Integer.但事实是,我在测试的时候 ...
- 怎么让Intellj Idea 把数据库的表映射成hibernate的domain对象
步骤如下: 第一步:连接数据源: 点击:idea右边的database.如下图所示: 或者你依次点击:view-->Tool windows--->database 然后你将看在如下点击下 ...
- 微信公众号开发之怎样将本机IP映射成外网域名
近期一个项目须要用到微信公众号的网页授权登录,在研究这个公众号的时候遇到各种困难,现将自己的一些心得总结一下. 我想进行微信公众号开发遇到的第一个困难就是微信公众号必须输入一个外网能够訪问的域名,在网 ...
- Ceph 块存储 创建的image 映射成块设备
将创建的volume1映射成块设备 [root@mysql-server ceph]# rbd map rbd_pool/volume1 rbd: sysfs write failed RBD ima ...
- mybatis枚举映射成tinyint
第一步:定义顶级枚举接口 public interface BaseEnum<E extends Enum<?>, T> { public T getCode(); publi ...
- Mybatis 查询tinyint(1)的数据库字段时会自动转换成boolean类型
解决方案:将字段的tinyint(1)变成tinyint(2)
随机推荐
- Navicat导入导出数据表
当我们对mysql数据库进行了误操作,造成某个数据表中的部分数据丢失时,肯定就要利用备份的数据库,对丢失部分的数据进行导出.导入操作了.Navicat工具正好给我们提供了一个数据表的导入导出功能. 1 ...
- git push 时不用每次都输入密码的方法
在本地克隆下来的git仓库中找到 .git 目录 (.git 目录是隐藏文件夹 在组织->文件夹和搜索选项-> 查看选项卡 -> 隐藏文件和文件夹 -> 显示隐藏的文件.文件夹 ...
- 接轨国际,碰撞更多科研火花——第八届ChinaSys大会专访微软亚洲研究院首席研究员张霖涛
作者:微软亚洲研究院实习生 徐祎雪 卢思奇 2015年6月5日至6日,由中国科学院深圳先进技术研究院先进计算与数字工程研究所主办的第八届中国计算机系统(ChinaSys)学术研讨会在厦门大学召开.来自 ...
- Spotlight 监控工具使用
监控MySQL数据库性能的工具:Spotlight on MySQL <转载> 我们的服务器数据库:是在windows2003上. 这款工具非常的花哨,界面很漂亮,自带报警. 1.创 ...
- lsync+rsync 实时同步(ubuntu16.04系统)
1.同步端需要安装 lsync/rsyncapt-get install lsyncd rsync2.生成ssh公钥,粘贴到目标机器里面3.创建配置文件mkdir /etc/lsyncdcat /et ...
- 阿里投资Magic Leap 是美酒还是毒药?
Leap 是美酒还是毒药?" title="阿里投资Magic Leap 是美酒还是毒药?"> 土豪阿里又摊上"大事"了!但这次不是让人头痛的假 ...
- iPhone8、Note8、Mate10硬上面部识别:是潮流还是无奈
对于手机厂商来说,时不时抛出几个全新概念当噱头来引起业界和大众的关注,已经成为了必然套路.其中有很多改变智能手机发展进程的技术--双摄像头.指纹识别.快充等,但也有很多纯粹来凑数,看似新潮却始终没 ...
- Spring aop(1)--- 寻找切面和代理对象执行流程源码分析
1.基于注解,首先我们是通过@EnableAspectJAutoProxy()这个注解开起AOP功能,这个注解会导入AspectJAutoProxyRegistrar组件从而将AnnotationAw ...
- Flutter Widgets 之 SnackBar
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 基础用法 应用程序有时候需要弹出消息提示用户,比如'网络连 ...
- c++获取屏幕大小
API: 要取得屏幕大小,可以用下面几个函数: # include <windows.h>int cx = GetSystemMetrics( SM_CXFULLSCREEN ); int ...