Mybatis进阶之自定义TypeHandler

本文介绍了在实际开发中如何使用MyBatis自定义TypeHandler来处理前端与数据库字段类型不一致的问题,例如将字符串'男'、'女'映射为tinyint类型的1和2。通过定义`GenderTypeHandler`类并配置,实现了数据转换。同时,文章深入解析了TypeHandler在MyBatis中的执行原理,包括参数设置和结果转换的过程,并探讨了此功能可能应用于的其他场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实际应用开发中的难免会有一些需求要自定义一个TypeHandler ,比如这样一个需求:前端传来的性别是 男, 女,但是数据库定义的字段却是tinyint 类型( 1:男 2:女)。此时可以自定义一个年龄的类型处理器,进行转换。

定义TypeHandler

package com.mtaite.study.mybatis.handler;

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.springframework.util.StringUtils;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


@MappedJdbcTypes(JdbcType.INTEGER)
@MappedTypes(String.class)
public class GenderTypeHandler extends BaseTypeHandler {

      //设置参数,这里将Java的String类型转换为JDBC的Integer类型
      @Override
      public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
           ps.setInt(i, parameter.toString().equals("男")? 1:2);
       }
      //  以下三个参数都是将查询的结果转换
      @Override
      public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
          return rs.getInt(columnName)==1?"男":"女";
     }
     @Override
     public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
       return rs.getInt(columnIndex)==1?"男":"女";
     }
     @Override
     public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
          return cs.getInt(columnIndex)==1?"男":"女";
     }
}

这里涉及到两个注解:

  1. @MappedTypes :指定与其关联的 Java 类型列表。 如果在 javaType 属性中也同时指定,则注解上的配置将被忽略。
  2. @MappedJdbcTypes :指定与其关联的 JDBC 类型列表。 如果在jdbcType 属性中也同时指定,则注解上的配置将被忽略。

配置Mybatis配置文件

配置mapper的xml文件中的字段

通过上面的配置就可以实现性别字段的数据转换了,可以拿源代码试试哦。

源码中如何执行TypeHandler

既然会使用TypeHandler 了,那么肯定要知道其中的执行原理了,在Mybatis中类型处理器是如何在JDBC 类型和Java 类型进行转换的,下面的将从源码角度详细介绍。

入参如何转换

肯定是发生在设置参数的过程中,详细的代码在PreparedStatementHandler 中的parameterize() 方法中,这个方法就是设置参数的方法。源码如下:

实际执行的是DefaultParameterHandler 中的setParameters 方法,如下:

从上面的源码中可以知道: typeHandler.setParameter(ps, i + 1,value, jdbcType); 就是调用类型处理器中的设置参数的方法,将Java 类型转换为JDBC 类型。

结果如何转换

这一过程肯定是发生在执行查询语句的过程中,其中的ResultSetHandler 这个组件就是对查询的结果进行处理的,那么肯定是发生在这一组件中的某个方法。 在PreparedStatementHandler 执行查询结束之后,调用的是ResultSetHandler 中的handleResultSets() 方法,对结果进行处理,如下:

最终是在DefaultResultSetHandler 中的getPropertyMappingValue() 方法中调用了TypeHandler 中的getResult() 方法,如下:

扩展:Mybatis提供了许多默认处理器

想想这个功能还可以用于什么场景呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值