当数据库中的字段类型和java实体类型不匹配时,mybatis将字段映射到实体属性上会出现一些转换异常

项目场景:

项目场景:当数据库中的字段类型和java实体类型不匹配时,mybatis将字段映射到实体属性上会出现一些转换异常

初始问题描述

比如在实体中存在一个Date类型的属性date
在这里插入图片描述
在sql表中存在对应的字段
在这里插入图片描述
但是在sql表中,该数据的类型为bigInt,存储的是1970年1月1日00:00:00到目标时间的毫秒数。
当你使用mybatis将表中的数据映射到实体中时,就会出现转换异常
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'birthday' from result set. Cause: java.sql.SQLDataException: Unsupported conversion from LONG to java.sql.Timestamp

初始问题解决

1.此时我们可以使用mybatis的TypeHandler进行类型转换处理(注意!!!!!!!此时这个handler是为了将数据库中的birthday(bigInt型)转换成java实体中的birthday(util.date型))

package com.itheima.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

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

/**
 * @author Watching
 * * @date 2022/5/11
 * * Describe:
 */
public class DateTypeHandler extends BaseTypeHandler<Date> {
    //将java类型转换成数据需要的类型
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
        long time = date.getTime();
        preparedStatement.setLong(i, time);//i是参数位置
        System.out.println("setNonNullParameter将java类型转换成数据需要的类型");
    }

    //将数据库中的类型转换成java类型
    //String参数 要转换的字段名称
    //ResultSet 查询出的结果集
    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
        System.out.println(s);
        long aLong = resultSet.getLong(s);
        Date date = new Date(aLong);
        System.out.println("getNullableResult将数据库中的类型转换成java类型");
        return date;
    }

    //将数据库中的类型转换成java类型
    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
        long aLong = resultSet.getLong(i);
        Date date = new Date(aLong);
        System.out.println("getNullableResult将数据库中的类型转换成java类型");
        return date;
    }

    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        long aLong = callableStatement.getLong(i);
        Date date = new Date(aLong);
        System.out.println("getNullableResult");
        return date;
    }
}

2.并且在mybatis核心文件中注册TypeHandler

    <!--注册类型转换驱动    也可以选择不在mybatis核心配置文件中配置(在核心文件中配置为全局配置,所有实体中符合BaseTypeHandler<T>中T类型的属性都会被转换),而在mapper配置文件中的某个特定字段上配置 避免某些实体中的属性符合转换要求但是实际上又不需要转换导致的异常-->
    <typeHandlers>
        <typeHandler handler="com.itheima.handler.DateTypeHandler"/>
    </typeHandlers>

3.此时再测试就可以获得成功结果啦
在这里插入图片描述

进阶问题

如果查询的表中的某个字段对应的实体属性符合BaseTypeHandler,但是该字段在数据库中的数据类型又不是bigInt,如
在这里插入图片描述

在这里插入图片描述
数据库中的ordertime是datetime类型

此时执行查询操作就会出现新的异常
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'ordertime' from result set. Cause: java.sql.SQLDataException: Unsupported conversion from DATETIME to java.lang.Long

为什么会出现这个异常呢? 因为我们上面的自定义TypeHandler的功能是将bigInt转换为util.Date
而此时该字段的类型为datetime

进阶问题解决:

1.将mybatis核心文件中的TypeHandler注册注释掉
在这里插入图片描述
2.在特定的字段上进行TypeHandler的注册
在这里插入图片描述

此时mybatis就只会对你指定的实体属性和字段进行转换,不会对所有符合的实体属性和字段就行转换

3.得到正确结果
在这里插入图片描述

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CLOB 类型是达梦数据库特有的数据类型,与其他数据库的数据类型不同。因此,在使用 MyBatis 查询达梦数据库的 CLOB 类型字段,需要进行特殊处理。 下面是一个示例代码,演示如何使用 MyBatis 查询达梦数据库的 CLOB 类型字段: 1. 在 MyBatis 配置文件添加类型处理器: ``` <typeHandlers> <typeHandler jdbcType="CLOB" javaType="java.lang.String" handler="com.example.ClobTypeHandler" /> </typeHandlers> ``` 其,`jdbcType` 表示数据库的数据类型,`javaType` 表示Java的数据类型,`handler` 表示自定义的类型处理器。 2. 自定义类型处理器: ``` public class ClobTypeHandler extends BaseTypeHandler<String> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { StringReader reader = new StringReader(parameter); ps.setCharacterStream(i, reader, parameter.length()); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { Reader reader = rs.getCharacterStream(columnName); if (reader == null) { return null; } StringBuilder sb = new StringBuilder(); char[] buffer = new char[4096]; int len = 0; while ((len = reader.read(buffer)) != -1) { sb.append(buffer, 0, len); } return sb.toString(); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { Reader reader = rs.getCharacterStream(columnIndex); if (reader == null) { return null; } StringBuilder sb = new StringBuilder(); char[] buffer = new char[4096]; int len = 0; while ((len = reader.read(buffer)) != -1) { sb.append(buffer, 0, len); } return sb.toString(); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { Reader reader = cs.getCharacterStream(columnIndex); if (reader == null) { return null; } StringBuilder sb = new StringBuilder(); char[] buffer = new char[4096]; int len = 0; while ((len = reader.read(buffer)) != -1) { sb.append(buffer, 0, len); } return sb.toString(); } } ``` 该类型处理器将 CLOB 类型转换Java 的 String 类型,并在查询结果返回。 3. 在 MyBatis 映射文件使用类型处理器: ``` <resultMap id="userResultMap" type="User"> <id column="id" property="id" /> <result column="name" property="name" /> <result column="description" property="description" jdbcType="CLOB" javaType="java.lang.String" typeHandler="com.example.ClobTypeHandler" /> </resultMap> ``` 其,`jdbcType` 表示数据库的数据类型,`javaType` 表示Java的数据类型,`typeHandler` 表示自定义的类型处理器。 通过以上步骤,你可以在 MyBatis 查询达梦数据库的 CLOB 类型字段,并将其转换Java 的 String 类型

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值