mybatis自定义字段类型的TypeHandler,并替换原有的TypeHandler

今天同事将项目改成连接db2数据库,然后登录系统就报错:

com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][t4][1092][13956][4.16.53] 数据转换无效:所请求转换的结果列类型错误。 ERRORCODE=-4461, SQLSTATE=42815
	at com.ibm.db2.jcc.am.fd.a(fd.java:739)
	at com.ibm.db2.jcc.am.fd.a(fd.java:60)
	at com.ibm.db2.jcc.am.fd.a(fd.java:120)
	at com.ibm.db2.jcc.am.ResultSet.getObject(ResultSet.java:1827)
	at com.ibm.db2.jcc.am.ResultSet.getObject(ResultSet.java:1841)
	at com.alibaba.druid.filter.FilterChainImpl.resultSet_getObject(FilterChainImpl.java:1431)
	at com.alibaba.druid.filter.FilterAdapter.resultSet_getObject(FilterAdapter.java:1719)
	at com.alibaba.druid.filter.FilterChainImpl.resultSet_getObject(FilterChainImpl.java:1427)
	at com.alibaba.druid.filter.stat.StatFilter.resultSet_getObject(StatFilter.java:855)
	at com.alibaba.druid.filter.FilterChainImpl.resultSet_getObject(FilterChainImpl.java:1427)
	at com.alibaba.druid.filter.FilterAdapter.resultSet_getObject(FilterAdapter.java:1719)
	at com.alibaba.druid.filter.FilterChainImpl.resultSet_getObject(FilterChainImpl.java:1427)
	at com.alibaba.druid.proxy.jdbc.ResultSetProxyImpl.getObject(ResultSetProxyImpl.java:1561)
	at com.alibaba.druid.pool.DruidPooledResultSet.getObject(DruidPooledResultSet.java:1777)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:69)
	at com.sun.proxy.$Proxy282.getObject(Unknown Source)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:38)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:28)
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)

跟踪发现是LocalDateTime和LocalDate类型转换handler报错。
换了几个版本的驱动,都不行,没办法只能重写mybatis里面这两个类型的handler,特别注意注解种的属性:includeNullJdbcType = true,否则替换不成功。

/**
 * Copyright 2009-2019 the original author or authors.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.xxx.mybatis.typehandler;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.LocalDateTimeTypeHandler;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * db2 LocalDateTime 转换有问题,这里重写
 *
 * @author Tomas Rohovsky
 * @since 3.4.5
 */
@MappedTypes(LocalDateTime.class)
@MappedJdbcTypes(value = JdbcType.TIMESTAMP, includeNullJdbcType = true)
public class DB2LocalDateTimeTypeHandler extends LocalDateTimeTypeHandler {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setObject(i, Timestamp.valueOf(parameter));
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Object object = rs.getObject(columnName);
        if (Objects.isNull(object)) {
            return null;
        }

        if (object instanceof Timestamp) {
            return ((Timestamp) object).toLocalDateTime();
        }
        return rs.getObject(columnName, LocalDateTime.class);
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Object object = rs.getObject(columnIndex);
        if (Objects.isNull(object)) {
            return null;
        }
        if (object instanceof Timestamp) {
            return ((Timestamp) object).toLocalDateTime();
        }
        return rs.getObject(columnIndex, LocalDateTime.class);
    }

    @Override
    public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Object object = cs.getObject(columnIndex);
        if (Objects.isNull(object)) {
            return null;
        }
        if (object instanceof Timestamp) {
            return ((Timestamp) object).toLocalDateTime();
        }
        return cs.getObject(columnIndex, LocalDateTime.class);
    }
}

/**
 * Copyright 2009-2019 the original author or authors.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.xxx.mybatis.typehandler;

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 java.sql.CallableStatement;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.Objects;

/**
 * @since 3.4.5
 * @author Tomas Rohovsky
 */
@MappedTypes(LocalDate.class)
@MappedJdbcTypes(value = JdbcType.DATE, includeNullJdbcType = true)
public class DB2LocalDateTypeHandler extends BaseTypeHandler<LocalDate> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDate parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setObject(i, Date.valueOf(parameter));
    }

    @Override
    public LocalDate getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Object object = rs.getObject(columnName);
        if (Objects.isNull(object)) {
            return null;
        }

        if (object instanceof Date) {
            return ((Date) object).toLocalDate();
        }
        return rs.getObject(columnName, LocalDate.class);
    }

    @Override
    public LocalDate getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Object object = rs.getObject(columnIndex);
        if (Objects.isNull(object)) {
            return null;
        }

        if (object instanceof Date) {
            return ((Date) object).toLocalDate();
        }
        return rs.getObject(columnIndex, LocalDate.class);
    }

    @Override
    public LocalDate getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Object object = cs.getObject(columnIndex);
        if (Objects.isNull(object)) {
            return null;
        }

        if (object instanceof Date) {
            return ((Date) object).toLocalDate();
        }
        return cs.getObject(columnIndex, LocalDate.class);
    }
}

最后一步,修改mybatis-plus的配置:

mybatis-plus:
  type-handlers-package: com.xxx.mybatis.typehandler

然后重启服务,日期格式类型转换已经不报错了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值