题目
MyBatis 是否可以映射枚举类型
答案
MyBatis 可以映射枚举类,不单可以映射枚举类,MyBatis 可以映射任何对象到表的一列上。映射方式为自定义一个 `TypeHandler` ,实现 `TypeHandler` 的 `setParameter()` 和 `getResult()` 接口方法。 `TypeHandler` 有两个作用:
- 一是完成从 Java Type 至 JDBC Type 的转换;
- 二是完成 JDBC Type 至 Java Type 的转换,体现为 `setParameter()` 和 `getResult()` 两个方法,分别代表设置 sql 问号占位符参数和获取列查询结果。
下面是一个简单的示例,展示如何自定义TypeHandler来映射枚举类:
首先,定义一个枚举类`Gender`:
```java
public enum Gender {
MALE,
FEMALE
}
```
然后,自定义一个实现 TypeHandler 接口的枚举类型处理器`GenderTypeHandler`:
```java
public class GenderTypeHandler implements TypeHandler<Gender> {
@Override
public void setParameter(PreparedStatement ps, int i, Gender parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
ps.setNull(i, Types.VARCHAR);
} else {
ps.setString(i, parameter.name());
}
}
@Override
public Gender getResult(ResultSet rs, String columnName) throws SQLException {
String value = rs.getString(columnName);
if (value == null) {
return null;
} else {
return Gender.valueOf(value);
}
}
@Override
public Gender getResult(ResultSet rs, int columnIndex) throws SQLException {
String value = rs.getString(columnIndex);
if (value == null) {
return null;
} else {
return Gender.valueOf(value);
}
}
@Override
public Gender getResult(CallableStatement cs, int columnIndex) throws SQLException {
String value = cs.getString(columnIndex);
if (value == null) {
return null;
} else {
return Gender.valueOf(value);
}
}
}
```
在上面的示例中,通过实现TypeHandler接口的setParameter()和getResult()方法,将枚举类型Gender与数据库中的列进行相互转换。
最后,**在 Mapper 接口中指定使用自定义的 TypeHandler**:
```java
public interface UserMapper {
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "gender", column = "gender", typeHandler = GenderTypeHandler.class)
})
@Select("SELECT * FROM user WHERE id = #{id}")
User getUserById(int id);
}
```
在上述示例中,**通过使用 @Result 注解指定 gender 属性使用自定义的 GenderTypeHandler 进行映射**。
