文章目录
前言
在使用 Mybitas 的时候我们一般很少关注数据库类型和 Java 类型转化这件事,其实 Mybatis 已经为我们做了这件工作,本文就枚举类型的使用进行一个小小的举例
typeHandler 类型处理器
无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。
类型处理器 | Java 类型 | JDBC 类型 |
---|---|---|
BooleanTypeHandler | java.lang.Boolean, boolean | 数据库兼容的 BOOLEAN |
ByteTypeHandler | java.lang.Byte, byte | 数据库兼容的 NUMERIC 或 BYTE |
ShortTypeHandler | java.lang.Short, short | 数据库兼容的 NUMERIC 或 SHORT INTEGER |
IntegerTypeHandler | java.lang.Integer, int | 数据库兼容的 NUMERIC 或 INTEGER |
LongTypeHandler | java.lang.Long, long | 数据库兼容的 NUMERIC 或 LONG INTEGER |
FloatTypeHandler | java.lang.Float, float | 数据库兼容的 NUMERIC 或 FLOAT |
DoubleTypeHandler | java.lang.Double, double | 数据库兼容的 NUMERIC 或 DOUBLE |
BigDecimalTypeHandler | java.math.BigDecimal | 数据库兼容的 NUMERIC 或 DECIMAL |
StringTypeHandler | java.lang.String | CHAR, VARCHAR |
ClobReaderTypeHandler | java.io.Reader | - |
ClobTypeHandler | java.lang.String | CLOB, LONGVARCHAR |
NStringTypeHandler | java.lang.String | NVARCHAR, NCHAR |
NClobTypeHandler | java.lang.String | NCLOB |
BlobInputStreamTypeHandler | java.io.InputStream | - |
ByteArrayTypeHandler | byte[] | 数据库兼容的字节流类型 |
BlobTypeHandler | byte[] | BLOB, LONGVARBINARY |
DateTypeHandler | java.util.Date | TIMESTAMP |
DateOnlyTypeHandler | java.util.Date | DATE |
TimeOnlyTypeHandler | java.util.Date | TIME |
SqlTimestampTypeHandler | java.sql.Timestamp | TIMESTAMP |
SqlDateTypeHandler | java.sql.Date | DATE |
SqlTimeTypeHandler | java.sql.Time | TIME |
ObjectTypeHandler | Any | OTHER 或未指定类型 |
EnumTypeHandler |
Enumeration Type | VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引) |
EnumOrdinalTypeHandler |
Enumeration Type | 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。 |
InstantTypeHandler | java.time.Instant | TIMESTAMP |
LocalDateTimeTypeHandler | java.time.LocalDateTime | TIMESTAMP |
LocalDateTypeHandler | java.time.LocalDate | DATE |
LocalTimeTypeHandler | java.time.LocalTime | TIME |
OffsetDateTimeTypeHandler | java.time.OffsetDateTime | TIMESTAMP |
OffsetTimeTypeHandler | java.time.OffsetTime | TIME |
ZonedDateTimeTypeHandler | java.time.ZonedDateTime | TIMESTAMP |
YearTypeHandler | java.time.Year | INTEGER |
MonthTypeHandler | java.time.Month | INTEGER |
YearMonthTypeHandler | java.time.YearMonth | VARCHAR or LONGVARCHAR |
JapaneseDateTypeHandler | java.time.chrono.JapaneseDate | DATE |
枚举类型默认的 typeHandler
上文已经说到,Mybatis 为不通类型的参数自动设置来不通的类型处理器,对于枚举类型来说,默认的类型处理器就是
EnumTypeHandler
,这样一来,其实我们可以直接使用枚举类型的参数,下面枚举类型的使用种的第一种情况就适用于这种默认情况。
Mybatis 结合枚举最简单的方式
我们需要先做点基础准备工作,简单说就是构造一个具有枚举类型成员变量的实体类,所以第一步自然是定义枚举类,考虑到枚举类型到多样化,我同时声明了3个枚举类
定义枚举类
一个属性一个枚举类就够了,这里展示三个枚举类是为类说明一下,默认情况下最终存到数据库到会是 枚举类型的名字 INIT
- 第一个
public enum Str1Enum {
INIT("初始状态"),
ACTIVE("激活状态"),
FREEZE("冻结状态");
private String name;
public String getName() {
return name;
}
Str1Enum(String name){
this.name=name;
}
}
- 第二个
public enum Str2Enum {
INIT("init","初始化"),
ACTIVE("active","激活"),
FREEZE("freeze","冻结");
private String key;
private String value;
public String getKey() {
return key;
}
public String getValue() {
return value;
}
Str2Enum(String key,String value){
this.key=key;
this.value=value;
}
}
- 第三个
public enum Str3Enum {
INIT(10,"初始化"),
ACTIVE(20,"激活"),
FREEZE(30,"冻结");
private int key;
private String value;
public int getKey() {
return key;
}
public String getValue() {
return value;
}
Str3Enum(int key,String value){
this.key=key;
this.value=value;
}
}
准备一个表
create table ENUM_DEMO
(
ID bigint not null
primary key,
STR1 varchar(32) null,
STR2 varchar(32) null,
STR3 varchar(32) null
);
最简单的方式
Mybatis+Maven 自动生成代码
Mybatis 自动生成代码配置 -Spring + Maven 环境
使用 Mybatis 默认的类型处理器,只需要在自动生成 Mybatis 相关内容的时候指定一下涉及字段的 javaType
<table tableName="ENUM_DEMO" domainObjectName="EnumDemoEntity" enableCountByExample="false"
enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false">
<columnOverride column="STR1" jdbcType="VARCHAR" javaType="com.bestcxx.stu.springmybatis.enums.Str1Enum"></columnOverride>
<columnOverride column="STR2" jdbcType="VARCHAR" javaType="com.bestcxx.stu.springmybatis.enums.Str2Enum"></columnOverride>
<columnOverride column="STR3" jdbcType="VARCHAR" javaType="com.bestcxx.stu.springmybatis.enums.Str3Enum"></columnOverride>
</table>
- 向数据库插入一条数据
@Test
public void test(){
EnumDemoEntity record=new EnumDemoEntity();
record.setId(1l);
record.setStr1(Str1Enum.INIT);
record.setStr2(Str2Enum.INIT);
record.setStr3(Str3Enum.INIT);
enumDemoEntityMapper.insert(record);
}
使用 Mybatis 的 EnumOrdinalTypeHandler
上文提到,Mybatis 自带的枚举类型的类型处理器是 EnumTypehandler,其会保存枚举的名称,Mybatis 自带了另外一种枚举类型c处理器
EnumOrdinalTypeHandler
,如上表中标红的部分,EnumTypeHandler 存储枚举的名称,EnumOrdinalTypeHandler 存储枚举的索引
类的路径
//EnumTypeHandler
org.apache.ibatis.type.EnumTypeHandler
//EnumOrdinalTypeHandler
org.apache.ibatis.type.EnumOrdinalTypeHandler
使用 EnumOrdinalTypeHandler 存储的是索引
需要修改数据库类型为 整形,而且EnumOrdinalTypeHandler 的起始数是0
create table ENUM_DEMO
(
ID bigint not null
primary key,
STR1 varchar(32) null,
STR2 varchar(32) null,
STR3 int null
);
如果使用 Mybatis 代码自动生成工具
<table tableName="ENUM_DEMO" domainObjectName="EnumDemoEntity" enableCountByExample="false"
enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false">
<columnOverride column="STR1" jdbcType="VARCHAR" javaType="com.bestcxx.stu.springmybatis.enums.Str1Enum"></columnOverride>
<columnOverride column="STR2" jdbcType="VARCHAR" javaType="com.bestcxx.stu.springmybatis.enums.Str2Enum"></columnOverride>
<columnOverride column="STR3" jdbcType="VARCHAR" javaType="com.bestcxx.stu.springmybatis.enums.Str3Enum" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"></columnOverride>
</table>
如果修改已有的 xml
- 搜索的部分
<resultMap id="BaseResultMap" type="com.bestcxx.stu.springmybatis.model.EnumDemoEntity" >
<id column="ID" property="id" jdbcType="BIGINT" />
<result column="STR1" property="str1" jdbcType="VARCHAR"/>
<result column="STR2" property="str2" jdbcType="VARCHAR"/>
<result column="STR3" property="str3" jdbcType="VARCHAR" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
</resultMap>
- 插入的部分
<insert id="insert" parameterType="com.bestcxx.stu.springmybatis.model.EnumDemoEntity" >
insert into ENUM_DEMO (ID, STR1, STR2,
STR3)
values (#{id,jdbcType=BIGINT}, #{str1,jdbcType=VARCHAR}, #{str2,jdbcType=VARCHAR},
#{str3,jdbcType=VARCHAR,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler})
</insert>
看数据库结果
STR3 字段由之前的 INIT 变为了索引序数 0
参考内容
[1]、http://www.mybatis.org/mybatis-3/zh/configuration.html#typeHandlers
[2]、《深入浅出 Mybatis 技术原理与实战》