mybatis自定义类型处理器
相关说明
本文以java枚举GenderEnum
与数据库表列类型char
相互转换为例进行示例说明。
-
现有Employee类
@Data @Builder @NoArgsConstructor @AllArgsConstructor public class Employee { /** 名字 */ private String name; /** 年龄 */ private Integer age; /** 性别 */ private GenderEnum gender; /** 座右铭 */ private String motto; }
-
Employee类对应的表结构为
编写类型处理器
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 自定义类型装换器:<br/>
* <ul>
* <li>方式一:继承{@link BaseTypeHandler}</li>
* <li>方式二:实现{@link TypeHandler}</li>
* </ul>
*
* <br><br>
* <p>
* 哪些类型可以相互转换,可通过{@link MappedTypes}和{@link MappedJdbcTypes}进行指定:<br/>
* <ul>
* <li>{@link MappedTypes}指定java类型</li>
* <li>{@link MappedJdbcTypes}指定jdbc类型</li>
* </ul>
*
* @author JustryDeng
* @since 2021/9/12 15:49:44
*/
@MappedTypes(value = {GenderEnum.class})
@MappedJdbcTypes(value = {JdbcType.CHAR})
public class GenderEnumHandler extends BaseTypeHandler<GenderEnum> {
/**
* 入库时调用
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, GenderEnum parameter, JdbcType jdbcType) throws SQLException {
// 具体调用ps的什么setXxx方法,要看你的数据类型
ps.setInt(i, parameter.getGender());
}
/**
* 出库时调用
*/
@Override
public GenderEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 具体调用rs的什么getXxx方法,要看你的数据类型
int i = rs.getInt(columnName);
if (i == 0) {
return GenderEnum.WOMAN;
}
if (i == 1) {
return GenderEnum.MAN;
}
throw new IllegalArgumentException("GenderEnum un-support gender " + i);
}
/**
* 出库时调用
*/
@Override
public GenderEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// 具体调用rs的什么getXxx方法,要看你的数据类型
int i = rs.getInt(columnIndex);
if (i == 0) {
return GenderEnum.WOMAN;
}
if (i == 1) {
return GenderEnum.MAN;
}
throw new IllegalArgumentException("GenderEnum un-support gender " + i);
}
/**
* 出库时调用
*/
@Override
public GenderEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// 具体调用rs的什么getXxx方法,要看你的数据类型
int i = cs.getInt(columnIndex);
if (i == 0) {
return GenderEnum.WOMAN;
}
if (i == 1) {
return GenderEnum.MAN;
}
throw new IllegalArgumentException("GenderEnum un-support gender " + i);
}
}
启用类型处理器
方式一:直接用mybatis总配置类注册处理器
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* mybatis类型处理器配置
*
* @author JustryDeng
* @since 2021/9/12 16:34:45
*/
@Component
public class MybatisTypeHandlerConfig {
final List<SqlSessionFactory> sqlSessionFactoryList;
public MybatisTypeHandlerConfig(@Autowired List<SqlSessionFactory> sqlSessionFactoryList) {
this.sqlSessionFactoryList = sqlSessionFactoryList;
}
@PostConstruct
public void initHandler () {
if (sqlSessionFactoryList == null) {
return;
}
sqlSessionFactoryList.forEach(sqlSessionFactory -> {
sqlSessionFactory.getConfiguration().getTypeHandlerRegistry().register(GenderEnumHandler.class);
});
}
}
方式二:通过配置文件指定处理器所处的包
# springboot项目,可通过指定处理器所在包(或祖先包)来启动处理器
mybatis.type-handlers-package=com.example.mybatis.handler
注:如果项目用了mybatis-plus
,那么mybatis.type-handlers-package可能会失效
,此时可以通过mybatis-plus.type-handlers-package
来指定。
方式三:在编写SQL时,指定类型处理器
-
使用xml写sql时
<insert id="insertByXml"> insert into employee(`name`, `age`, `gender`, `motto`) values (#{e.name}, #{e.age}, #{e.gender,typeHandler=com.example.mybatis.handler.GenderEnumHandler}, #{e.motto}) </insert> <select id="selectByXml" resultMap="selectByXmlRM"> select `name`, age, gender, motto from employee order by id desc limit 1 </select> <resultMap id="selectByXmlRM" type="com.example.mybatis.model.Employee"> <result property="name" column="name"/> <result property="age" column="age"/> <result property="gender" column="gender" typeHandler="com.example.mybatis.handler.GenderEnumHandler"/> <result property="motto" column="motto"/> </resultMap>
-
使用注解写sql时
@Insert("insert into employee(`name`, `age`, `gender`, `motto`) values " + "(#{e.name}, #{e.age}, #{e.gender,typeHandler=com.example.mybatis.handler.GenderEnumHandler}, #{e.motto})") int insert(@Param("e") Employee e); @Select("select `name`,age,gender,motto from employee order by id desc limit 1") @Results(value = { // 其余查询列没有啥特殊性的,可不指定@Result,也是能正常查出来的(,当然,你非要指定也可以) @Result(column = "gender", property = "gender", typeHandler = GenderEnumHandler.class), }) Employee select();
相关资料