说明
MyBatis本身自带了常规数据类型(如Integer、String、LocalDate)的TypeHandler(IntegerTypeHandler、StringTypeHandler、LocalDateTypeHandler)。但是在实际业务开发中,往往会有需要在枚举类和数据库字段间进行映射的需求,此时就需要自定义TypeHandler,并在xml文件中配置对应自定义的TypeHandler。
实体类中的性别字段gender为GenderEnum类型,数据库中的性别字段gender为int类型。
开发样例
性别枚举类GenderEnum:
import lombok.Getter;
@Getter
public enum GenderEnum {
MALE(0, "male"),
FEMALE(1, "female"),
UNKNOW(2, "unknow");
private int value;
private String gender;
GenderEnum(int value, String gender) {
this.value = value;
this.gender = gender;
}
public static GenderEnum getGenderEnum(int value) {
for (GenderEnum genderEnum : GenderEnum.values()) {
if (genderEnum.getValue() == value) {
return genderEnum;
}
}
return GenderEnum.UNKNOW;
}
}
编写TypeHandler:
import com.education.tutor.enums.GenderEnum;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class GenderTypeHandler implements TypeHandler<GenderEnum> {
@Override
public void setParameter(PreparedStatement ps, int i, GenderEnum parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.getValue());
}
@Override
public GenderEnum getResult(ResultSet rs, String columnName) throws SQLException {
int value = rs.getInt(columnName);
return GenderEnum.getGenderEnum(value);
}
@Override
public GenderEnum getResult(ResultSet rs, int columnIndex) throws SQLException {
int value = rs.getInt(columnIndex);
return GenderEnum.getGenderEnum(value);
}
@Override
public GenderEnum getResult(CallableStatement cs, int columnIndex) throws SQLException {
int value = cs.getInt(columnIndex);
return GenderEnum.getGenderEnum(value);
}
}
注册TypeHandler
在SpringBoot 3.5.0中实测时,不注册也可以。
1、通过xml配置文件注册
1.1、在application.properties添加xml文件路径:
mybatis.config-location=classpath:mapper/mybatis-config.xml
2.2、在mybatis-config.xml中注册TypeHandler
<?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>
<typeHandlers>
<typeHandler handler="com.example.handler.GenderTypeHandler"/>
</typeHandlers>
</configuration>
注:<configuration>
标签下的子标签(如<typeHandlers>
、<plugins>
、<mappers>
)有顺序要求,顺序不对会报错
2、通过Druid在配置文件中注册
2.1、在xml中引入Druid依赖:
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.25</version>
</dependency>
2.2、在Druid配置文件返回SqlSessionFactory对象的方法中,添加自定义TypeHandler:
@Bean
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
// 添加自定义TypeHandler
factoryBean.addTypeHandlers(new GenderTypeHandler());
return factoryBean.getObject();
}
使用
在Insert中使用:
INSERT INTO `person_info`(`gender`)
VALUES (#{item.gender, typeHandler=com.example.handler.GenderTypeHandler})
在Update中使用:
UPDATE `person_info` SET
`gender` = #{item.gender, typeHandler=com.example.handler.GenderTypeHandler}
WHERE `id` = #{item.id}
在Where条件语句中使用:
DELETE FROM `person_info`
WHERE `gender` = #{gender, typeHandler=com.example.handler.GenderTypeHandler}
在ResultMap中使用:
<result column="gender" property="gender" typeHandler="com.education.tutor.config.GenderTypeHandler"/>