文章目录
mybatis 中使用枚举1. 内置枚举转换器1.1 内置枚举转换器介绍1.1.1 EnumTypeHandler1.1.2 EnumOrdinalTypeHandler
1.2 内置枚举转换器使用
2. 自定义类型转换器2.1 BaseTypeHandler 抽象类2.2 自定义枚举转换器实现2.2.1 枚举接口2.2.2 自定义类型转换器
2.3 自定义枚举转换器测试2.3.1 用户实体对象2.3.2 控制层2.3.3 接口层2.3.4 接口实现层2.3.5 持久层2.3.6 mybatis 配置文件2.3.7 mybatis 映射文件
2.4 数据库脚本2.5 接口测试2.6 Reference
mybatis 中使用枚举
1. 内置枚举转换器
1.1 内置枚举转换器介绍
1.1.1 EnumTypeHandler
默认的枚举转换器,该转换器将枚举实例转换为实例名称的字符串,即将 SexEnum.MAN 转换 MAN
1.1.2 EnumOrdinalTypeHandler
将枚举实例的 ordinal 属性作为取值,即 SexEnum.MAN 转换为 0, SexEnum.WOMAN转换为 1
MyBatis内置枚举转换器
org.apache.ibatis.type.EnumTypeHandlerorg.apache.ibatis.type.EnumOrdinalTypeHandler
1.2 内置枚举转换器使用
mybatis-config.xml
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.answer.aal.entity.StatusEnum" />
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.answer.aal.entity.SexEnum" />
</typeHandlers>
2. 自定义类型转换器
2.1 BaseTypeHandler 抽象类
public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {
public abstract void setNonNullParameter(PreparedStatement ps
, int i
, T parameter
, JdbcType jdbcType
)
throws SQLException
;
public abstract T
getNullableResult(ResultSet rs
, String columnName
) throws SQLException
;
public abstract T
getNullableResult(ResultSet rs
, int columnIndex
) throws SQLException
;
public abstract T
getNullableResult(CallableStatement cs
, int columnIndex
) throws SQLException
;
}
2.2 自定义枚举转换器实现
2.2.1 枚举接口
枚举通用行为接口: IEnum
public interface IEnum<E
extends Enum<?>, T
> {
T
getValue();
}
性别枚举: SexEnum
public enum SexEnum
implements IEnum<EducationEnum, Integer> {
MAN(0),
WOMAN(1);
private int value
;
SexEnum(int value
) {
this.value
= value
;
}
@Override
public Integer
getValue() {
return value
;
}
}
学历枚举: EducationEnum
public enum EducationEnum
implements IEnum<EducationEnum, String> {
PRIMARY_SCHOOL("PRIMARY"),
JUNIOR_SCHOOL("JUNIOR"),
HIGH_SCHOOL("HIGH"),
UNIVERSITY_SCHOOL("UNIVERSITY")
;
private String value
;
EducationEnum(String value
) {
this.value
= value
;
}
@Override
public String
getValue() {
return value
;
}
}
2.2.2 自定义类型转换器
import org
.apache
.ibatis
.type
.BaseTypeHandler
;
import org
.apache
.ibatis
.type
.JdbcType
;
import org
.apache
.ibatis
.type
.MappedTypes
;
import java
.sql
.CallableStatement
;
import java
.sql
.PreparedStatement
;
import java
.sql
.ResultSet
;
import java
.sql
.SQLException
;
import java
.util
.Objects
;
@MappedTypes(value
= {SexEnum
.class, EducationEnum
.class})
public class BaseEnumTypeHandler<E
extends Enum<E> & IEnum
> extends BaseTypeHandler<E> {
private Class
<E> type
;
private E
[] enums
;
public BaseEnumTypeHandler() {
}
public BaseEnumTypeHandler(Class
<E> type
) {
if (type
== null
) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type
= type
;
this.enums
= type
.getEnumConstants();
if (this.enums
== null
) {
throw new IllegalArgumentException(type
.getSimpleName()
+ " does not represent an enum type.");
}
}
@Override
public void setNonNullParameter(PreparedStatement ps
, int i
, E parameter
,
JdbcType jdbcType
) throws SQLException
{
if (jdbcType
== null
) {
ps
.setString(i
, Objects
.toString(parameter
.getValue()));
} else {
ps
.setObject(i
, parameter
.getValue(), jdbcType
.TYPE_CODE
);
}
}
@Override
public E
getNullableResult(ResultSet rs
, String columnName
)
throws SQLException
{
String i
= rs
.getString(columnName
);
if (rs
.wasNull()) {
return null
;
} else {
return locateEnumStatus(i
);
}
}
@Override
public E
getNullableResult(ResultSet rs
, int columnIndex
)
throws SQLException
{
String i
= rs
.getString(columnIndex
);
if (rs
.wasNull()) {
return null
;
} else {
return locateEnumStatus(i
);
}
}
@Override
public E
getNullableResult(CallableStatement cs
, int columnIndex
)
throws SQLException
{
String i
= cs
.getString(columnIndex
);
if (cs
.wasNull()) {
return null
;
} else {
return locateEnumStatus(i
);
}
}
private E
locateEnumStatus(String value
) {
for (E e
: enums
) {
if (Objects
.toString(e
.getValue()).equals(value
)) {
return e
;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + value
+ ",请核对"
+ type
.getSimpleName());
}
}
注意: 如果使用了 @MappedTypes 注解, 需要在 application.properties 中添加如下配置
# 类型处理器类所在的包路径. eg: BaseEnumTypeHandler
mybatis.type-handlers-package=com.answer.aal.entity
否则, 直接在 mybatis 配置文件 mybatis-config.xml 添加如下配置
<typeHandlers>
<typeHandler handler="com.answer.aal.entity.BaseEnumTypeHandler" javaType="com.answer.aal.entity.EducationEnum" />
<typeHandler handler="com.answer.aal.entity.BaseEnumTypeHandler" javaType="com.answer.aal.entity.SexEnum" />
</typeHandlers>
2.3 自定义枚举转换器测试
2.3.1 用户实体对象
import com
.fasterxml
.jackson
.annotation
.JsonFormat
;
import lombok
.Data
;
import lombok
.NoArgsConstructor
;
import java
.util
.Date
;
@Data
@NoArgsConstructor
public class User {
private Long id
;
private String userName
;
private SexEnum sex
;
@JsonFormat(pattern
= "yyyy-MM-dd")
private Date birthDay
;
private EducationEnum education
;
@JsonFormat(pattern
= "yyyy-MM-dd HH-mm-ss")
private Date createTime
;
@JsonFormat(pattern
= "yyyy-MM-dd HH-mm-ss")
private Date updateTime
;
public User(String userName
, SexEnum sex
, Date birthDay
, EducationEnum education
, Date createTime
, Date updateTime
) {
this.userName
= userName
;
this.sex
= sex
;
this.birthDay
= birthDay
;
this.education
= education
;
this.createTime
= createTime
;
this.updateTime
= updateTime
;
}
}
2.3.2 控制层
import com
.answer
.aal
.entity
.SexEnum
;
import com
.answer
.aal
.entity
.EducationEnum
;
import com
.answer
.aal
.entity
.User
;
import com
.answer
.aal
.service
.IUserService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.web
.bind
.annotation
.PathVariable
;
import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
import org
.springframework
.web
.bind
.annotation
.RestController
;
import java
.util
.Date
;
import java
.util
.List
;
@RestController
@RequestMapping(value
= "/user")
public class UserController {
@Autowired
private IUserService userService
;
@RequestMapping("findUsers")
public List
<User> findUsers() {
return userService
.findUsers();
}
@RequestMapping("finUserById/{id}")
public User
finUserById(@PathVariable("id") Long id
) {
return userService
.findUserById(id
);
}
@RequestMapping("insert")
public Long
insert(){
User user
= new User("AnsweAIL", SexEnum
.MAN
, new Date(), EducationEnum
.HIGH_SCHOOL
, new Date(), new Date());
return userService
.insertUer(user
);
}
}
2.3.3 接口层
import com
.answer
.aal
.entity
.User
;
import java
.util
.List
;
public interface IUserService {
List
<User> findUsers();
User
findUserById(Long id
);
Long
insertUer(User user
);
}
2.3.4 接口实现层
import com
.answer
.aal
.dao
.UserDao
;
import com
.answer
.aal
.entity
.User
;
import com
.answer
.aal
.service
.IUserService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Service
;
import java
.util
.List
;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserDao userDao
;
@Override
public List
<User> findUsers() {
return userDao
.findUsers();
}
@Override
public User
findUserById(Long id
) {
return userDao
.findUserById(id
);
}
@Override
public Long
insertUer(User user
) {
return userDao
.insertUer(user
);
}
}
2.3.5 持久层
import com
.answer
.aal
.entity
.User
;
import java
.util
.List
;
public interface UserDao {
List
<User> findUsers();
User
findUserById(Long id
);
Long
insertUer(User user
);
}
2.3.6 mybatis 配置文件
<?xml version
="1.0" encoding
="UTF-8" ?>
<!DOCTYPE configuration PUBLIC
"-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name
="mapUnderscoreToCamelCase" value
="true"/>
</settings
>
<typeAliases>
<typeAlias alias
="User" type
="com.answer.aal.entity.User"/>
</typeAliases
>
<typeHandlers>
<!-- 如果此处配置了映射
, 则 BaseEnumTypeHandler 中就不需要
@MappedTypes 注解和 application
.xml 中不需要设置属性 mybatis
.type
-handlers
-package 值
-->
<typeHandler handler
="com.answer.aal.entity.BaseEnumTypeHandler" javaType
="com.answer.xsf.entity.EducationEnum" />
<typeHandler handler
="com.answer.xsf.entity.BaseEnumTypeHandler" javaType
="com.answer.aal.entity.SexEnum" />
</typeHandlers
>
</configuration
>
注意: 如果 BaseEnumTypeHandler 中设置了 @MappedTypes 注解, 此步骤 mybatis 配置文件 可省去
2.3.7 mybatis 映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.answer.aal.dao.UserDao" >
<resultMap id="user_mapper" type="User">
<id column="id" property="id" jdbcType="BIGINT" />
<result column="user_name" property="userName" jdbcType="VARCHAR" />
<result column="sex" property="sex" />
<result column="birth_day" property="birthDay" jdbcType="DATE" />
<result column="education" property="education" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="user_columns">
id, user_name, sex, birth_day, education, create_time, update_time
</sql>
<select id="findUsers" resultMap="user_mapper">
select
<include refid="user_columns" />
from sf_user
</select>
<select id="findUserById" resultMap="user_mapper">
select
<include refid="user_columns" />
from sf_user
where id = #{id}
</select>
<insert id="insertUer" useGeneratedKeys="true" keyProperty="id">
insert into sf_user
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="userName != null" >user_name,
</if>
<if test="sex != null" >sex,
</if>
<if test="birthDay != null" >birth_day,
</if>
<if test="education != null" >education,
</if>
<if test="createTime != null" >create_time,
</if>
<if test="updateTime != null" >update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="userName != null" >#{userName},
</if>
<if test="sex != null" >#{sex},
</if>
<if test="birthDay != null" >#{birthDay},
</if>
<if test="education != null" >#{education},
</if>
<if test="createTime != null" >#{createTime},
</if>
<if test="updateTime != null" >#{updateTime},
</if>
</trim>
</insert>
</mapper>
2.4 数据库脚本
CREATE TABLE `sf_user
` (
`id
` bigint(18) NOT NULL AUTO_INCREMENT,
`user_name
` varchar(20) DEFAULT NULL,
`sex
` enum('1','0') DEFAULT '0',
`birth_day
` date DEFAULT NULL,
`education
` enum('UNIVERSITY','HIGH','JUNIOR','PRIMARY') DEFAULT 'PRIMARY',
`create_time
` datetime DEFAULT NULL,
`update_time
` datetime DEFAULT NULL,
PRIMARY KEY (`id
`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
;
2.5 接口测试
2.6 Reference
github 源码地址 如何在MyBatis中优雅的使用枚举 学习Spring Boot:(十二)Mybatis 中自定义枚举转换器