MyBatis(mybatis_plus)中TypeHandler的使用教程

MyBatis(mybatis_plus)中TypeHandler的使用教程

一.TypeHandler作用及其使用场景

在我们平常开发操作数据库时,查询、插入数据等操作行为,有时会报数据类型不匹配异常,就可以得知数据的类型是不唯一的必然是多种不同的数据类型。并且我们必须要明确的一点就是java作为一门编程语言有自己的数据类型,数据库也是有自己的数据类型的。

jdbc数据类型:org.apache.ibatis.type.JdbcType 此枚举就是所有的数据库支持类型

java数据类型:int、long、string、...

一定要分清,例如java重的date数据插入到数据库中,应该是已经转换成了数据库的某种类型,必然跟java已经没有关系了。中间有一些我们看不见的操作做了数据处理。

假设此时的java类型与数据库数据类型是一样的,哪么其他语言中的日期数据插入数据库时又该怎么解释,例如C#操作数据库存入时间类型,C#与java肯定没有关系吧。所以每种语言与数据库之间有种数据类型关系对应。

思考:

因为java与数据库各自有数据类型,所以在将java数据存入数据库前中间是否有其他操作,是我们看不见的,不然java数据怎么知道自己与哪个jdbc数据类型匹配?

复制代码
答:mybatis框架为每种数据类型做了默认的关系对应,BaseTypeHandler的所有实现类,就是来做这些处理的。

例如:java中的date插入数据库时是jdbc哪种类型,怎么就是这种类型? 中间具体有什么操作?

复制代码
答:DateTypeHandler就是来解决date数据类型的处理。

二.TypeHandler使用

我们想要自定义去处理Java和JDBC的数据类型转换时,需要实现TypeHandler接口,该接口源码如下:

复制代码
//此接口作用是用于指定jdbc与java的数据类型间对应关系处理。
public interface TypeHandler<T> {
  // 保存操作,数据入库之前时数据处理
  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
  //下面三个则是,从数据库加载数据后,vo对象封装前的数据处理
  T getResult(ResultSet rs, String columnName) throws SQLException;
  T getResult(ResultSet rs, int columnIndex) throws SQLException;
  T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}

JsonIntegerTypeHandler 实现Integer和字符串互转

复制代码
public class JsonIntegerTypeHandler extends BaseTypeHandler<Integer> {
    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Integer parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, toJson(parameter));
    }

    @Override
    public Integer getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return this.toObject(rs.getString(columnName));
    }

    @Override
    public Integer getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return this.toObject(rs.getString(columnIndex));
    }

    @Override
    public Integer getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return this.toObject(cs.getString(columnIndex));
    }

    private String toJson(Integer params) {
        try {
            String copyObject = IotDbUtils.copyObject(params);
            return copyObject;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private Integer toObject(String content) {
        if (content != null && !content.isEmpty()) {
            try {
                System.out.println("1111111111111"+content);
                return (Integer) mapper.readValue(content, Integer.class);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            return null;
        }
    }
}

Mapper.xml

查询

查询的时候 你转的那个字段就配置哪个字段

复制代码
    <resultMap id="DmpDeviceReportResult" type="com.chinaunicom.iotdb.domain.DmpDeviceReportInformation" >
        <result column="Time" property="timestamp" />

        <result column="type" jdbcType="INTEGER"
                property="type" typeHandler="com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler"/>
        

    </resultMap>

  <select id="listDeviceReportInformation" resultMap="DmpDeviceReportResult">
        select trace_id, imei, topic, information, interaction_time,type
        from dmp_device_report_information
        where imei = #{serialNumber}
        <if test="beginTime != null and endTime != null">
            and interaction_time between #{beginTime} and #{endTime}
        </if>
        <if test="traceId != null and traceId != ''">
            and trace_id = #{traceId}
        </if>
        limit #{pageSize}  offset #{pageNum}
    </select>

新增

复制代码
<insert id="add" parameterType="com.chinaunicom.iotdb.domain.DmpDeviceReportInformation">
        INSERT INTO root.device.dmp_device_report_information
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="null != type ">
                type,
            </if>
            <if test="null != traceId and '' != traceId">
                trace_id,
            </if>
            <if test="null != imei and '' != imei">
                imei,
            </if>
            <if test="null != topic and '' != topic">
                topic,
            </if>
            <if test="null != information and '' != information">
                information,
            </if>
            <if test="null != interactionTime  and '' != interactionTime ">
                interaction_time,
            </if>
            <if test="null != organizationId ">
                organization_id
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="null != type ">
                #{type,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler },
            </if>
            <if test="null != traceId and '' != traceId">
                #{traceId,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler },
            </if>
            <if test="null != imei and '' != imei">
                #{imei,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler },
            </if>
            <if test="null != topic and '' != topic">
                #{topic,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler },
            </if>
            <if test="null != information and '' != information">
                #{information,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler },
            </if>
            <if test="null != interactionTime and '' != interactionTime ">
                #{interactionTime,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler },
            </if>
            <if test="null != organizationId ">
                #{organizationId,typeHandler=com.chinaunicom.iotdb.handler.JsonIntegerTypeHandler },
            </if>
        </trim>
    </insert>

mybatisPlus中使用

类注解 @TableName(autoResultMap = true)

参数注解 @TableField(typeHandler = JsonIntegerTypeHandler.class)

复制代码
@Data
@TableName(autoResultMap = true)
public class DmpDeviceReportInformation implements Serializable
{
    private static final long serialVersionUID = 1L;

    private Long id;

    /**
     * 消息类型1:消息上报 2:消息下发
     */
 @TableField(typeHandler = JsonIntegerTypeHandler.class)
    private Integer type;
    }

注意: 如果使用自己的mapper查询 要选择mybaits的形式

要想全局生效的话

复制代码
mybatis-plus:
   type-handlers-package: com.chinaunicom.iotdb.handler
相关推荐
麦聪聊数据14 分钟前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务15 分钟前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
程序员侠客行1 小时前
Mybatis连接池实现及池化模式
java·后端·架构·mybatis
Goat恶霸詹姆斯2 小时前
mysql常用语句
数据库·mysql·oracle
大模型玩家七七2 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
曾经的三心草2 小时前
redis-9-哨兵
数据库·redis·bootstrap
明哥说编程2 小时前
Dataverse自定义表查询优化:D365集成大数据量提速实战【索引配置】
数据库·查询优化·dataverse·dataverse自定义表·索引配置·d365集成·大数据量提速
xiaowu0802 小时前
C# 拆解 “显式接口实现 + 子类强类型扩展” 的设计思想
数据库·oracle
讯方洋哥3 小时前
HarmonyOS App开发——关系型数据库应用App开发
数据库·harmonyos
惊讶的猫3 小时前
Redis持久化介绍
数据库·redis·缓存