mybatis mysql枚举类型转换_Mybatis枚举类映射使用详解

1. 前言

刚入手spring-boot还不太熟练,先弄了个空的框架,然后写了个简单的用户查询,没啥挑战性。然后想起来之前一直对枚举不太了解,而用户的性别正好可以用枚举类型来表示(male, female)。于是就开始了自己的挖坑之旅。

本文主要分为三个部分:

mybatis自带枚举类型转换

自定义枚举类型转换

mybatis类型转换深入理解(将在下一篇介绍)

2. mybatis自带枚举类型转换

mybatis内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler。

EnumTypeHandler

这是默认的枚举转换器,该转换器将枚举实例转换为实例名称的字符串,即将ComputerState.OPEN转换OPEN。

EnumOrdinalTypeHandler

顾名思义这个转换器将枚举实例的ordinal属性作为取值,即ComputerState.OPEN转换为0,ComputerState.CLOSE转换为1。

使用方法

建表

CREATE TABLE `users` (

`id` int(13) NOT NULL AUTO_INCREMENT COMMENT '主键',

`username` varchar(33) DEFAULT NULL COMMENT '姓名',

`sex` varchar(8) DEFAULT NULL COMMENT '性别',

`age` int(3) DEFAULT NULL COMMENT '年龄',

`money` double DEFAULT NULL COMMENT '账户余额',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

创建枚举

public enum UserSexEnum {

MALE,

FEMALE;

}

创建实体类

public class User {

private int id;

private String username;

private UserSexEnum sex;

private int age;

private double money;

public User() {

super();

}

public User(String username, UserSexEnum sex, int age, double money) {

super();

this.username = username;

this.sex = sex;

this.age = age;

this.money = money;

}

// getter和setter方法不在此赘述

}

创建映射接口

public interface UserMapper {

List getAll();

void insert(User user);

}

配置xml文件

id, username, sex, age, money

SELECT

FROM users

INSERT INTO

users

(username, sex, age, money)

VALUES

(#{username}, #{sex}, #{age}, #{money})

测试

@RunWith(SpringRunner.class)

@SpringBootTest

public class UserMapperTest {

@Autowired

private UserMapper userMapper;

@Test

public void testInsert(){

userMapper.insert(new User("aaa", UserSexEnum.MALE, 18, 2.5));

userMapper.insert(new User("bbb", UserSexEnum.FEMALE, 24, 8.6));

userMapper.insert(new User("ccc", UserSexEnum.FEMALE, 21, 5.4));

Assert.assertEquals(3, userMapper.getAll().size());

}

}

使用EnumOrdinalTypeHandler的方法和默认的差不多,只是需要指定一下typeHandler

创建枚举

public enum UserSexEnum {

MALE(0,"男"),

FEMALE(1,"女");

private int sex;

private String sexName;

UserSexEnum(int sex, String sexName) {

this.sex = sex;

this.sexName = sexName;

}

public int getSex() {

return sex;

}

public String getSexName() {

return sexName;

}

}

修改xml配置

, #{sex, typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},

3. 自定义枚举类型转换

在日常编码的过程中,我们经常会遇到用某个数值来表示某种状态、类型或者阶段的情况,比如有这样一个枚举:

public enum OrderStatus {

CREATE(10, "创建"),

PAYING(13, "支付中"),

IN_PROGRESS(21, "支付成功"),

FAILED(36, "支付失败"),

REVERSED(48, "取消订单");

private int value;

private String desc;

OrderStatus(int value, String desc) {

this.value = value;

this.desc = desc;

}

public int getValue() {

return value;

}

public String getDesc() {

return desc;

}

}

通常我们希望将表示状态的数值存入数据库,即OrderStatus.PAYING存入数据库取值为13。很明显上述两个内置的枚举转换器都不能满足我们的需求,所以我们需要自定义一个枚举转换器。

MyBatis 提供了 org.apache.ibatis.type.BaseTypeHandler 类用于我们自己扩展类型转换器,上面的 EnumTypeHandler 和 EnumOrdinalTypeHandler 也都实现了这个接口。

public class EnumOrderStatusHandler extends BaseTypeHandler {

/**

* 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现

* @param type 配置文件中设置的转换类

*/

public EnumOrderStatusHandler(Class type) {

if (type == null)

throw new IllegalArgumentException("Type argument cannot be null");

}

/**

* 用于定义设置参数时,该如何把Java类型的参数转换为对应的数据库类型

*/

@Override

public void setNonNullParameter(PreparedStatement ps, int i, OrderStatus parameter, JdbcType jdbcType)

throws SQLException {

// 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型

// ps.setString

ps.setInt(i, parameter.getValue());

}

/**

* 用于定义通过字段名称获取字段数据时,如何把数据库类型转换为对应的Java类型

*/

@Override

public OrderStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {

// 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型

// String i = rs.getString(columnName);

int i = rs.getInt(columnName);

if (rs.wasNull()) {

return null;

} else {

// 根据数据库中的值,定位Enum子类

return locateEnum(i);

}

}

/**

* 用于定义通过字段索引获取字段数据时,如何把数据库类型转换为对应的Java类型

* @param rs

* @param columnIndex

* @return

* @throws SQLException

*/

@Override

public OrderStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

// 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型

// String i = rs.getString(columnIndex);

int i = rs.getInt(columnIndex);

if (rs.wasNull()) {

return null;

} else {

// 根据数据库中的值,定位Enum子类

return locateEnum(i);

}

}

/**

* 用定义调用存储过程后,如何把数据库类型转换为对应的Java类型

* @param cs

* @param columnIndex

* @return

* @throws SQLException

*/

@Override

public OrderStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {

// 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型

// String i = cs.getString(columnIndex);

int i = cs.getInt(columnIndex);

if (cs.wasNull()) {

return null;

} else {

// 根据数据库中的值,定位Enum子类

return locateEnum(i);

}

}

/**

* 枚举类型转换

* @param value 数据库中存储的自定义属性

* @return value对应的枚举类

*/

private OrderStatus locateEnum(int value) {

for (OrderStatus status : OrderStatus.values()) {

if (status.getValue() == value) {

return status;

}

}

throw new IllegalArgumentException("未知的枚举类型:" + value);

}

}

!!!还有更高级的用法,可以简化MyBatis的配置文件维护。具体参考第三篇文章

参考链接

你可能感兴趣的:(mybatis,mysql枚举类型转换)