shardingsphere+mybatis LocalDateTime转换报错java.time.LocalDateTime cannot be cast to java.sql.Timestamp

报错信息

java.time.LocalDateTime cannot be cast to java.sql.Timestamp

Caused by: java.lang.ClassCastException: java.time.LocalDateTime cannot be cast to java.sql.Timestamp
	at org.apache.shardingsphere.shardingjdbc.jdbc.core.resultset.ShardingResultSet.getTimestamp(ShardingResultSet.java:251)
	at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source)
	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.$Proxy166.getTimestamp(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:81)
	... 166 common frames omitted

问题分析

java 实体类中的字段类型为LocalDateTime,mysql 表中字段类型为datetime
未使用shardingsphere之前一切正常,使用shardingsphere之后才出现的这个错误
从报错信息上看是调用了org.apache.shardingsphere.shardingjdbc.jdbc.core.resultset.ShardingResultSet.getTimestamp()方法导致的 类型转换异常

// 在ShardingResultSet中getTimestamp方法如下
@Override
public Timestamp getTimestamp(final String columnLabel) throws SQLException {
	int columnIndex = columnLabelAndIndexMap.get(columnLabel);
    return (Timestamp) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Timestamp.class), Timestamp.class);
}

在网上查了很多
有说依赖版本不兼容的
有说日期格式不正确的
有说要增加mybatis-typehandlers-jsr310依赖的
还有的说要修改数据库字段类型为timestamp
试了很多方法,问题还是存在,那我就另辟蹊径,下面就是我的解决方法

解决方案

重写LocalDateTimeTypeHandler 避免调用getTimestamp()方法
代码如下

package com.zixiu.framework.handler;

import org.apache.ibatis.type.JdbcType;
import org.springframework.stereotype.Component;

import java.sql.*;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * 重写LocalDateTimeTypeHandler ,解决shardingsphere + mybatis LocalDateTime转换问题
 *
 * @author ZiXiu
 */
@Component
public class LocalDateTimeTypeHandler extends org.apache.ibatis.type.LocalDateTimeTypeHandler {
    public LocalDateTimeTypeHandler() {
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) throws SQLException {
        ps.setTimestamp(i, new Timestamp(this.toTimeMillis(parameter)));
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Object object = rs.getObject(columnName);
        return object == null ? null : this.toLocalDateTime(object);
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Object object = rs.getObject(columnIndex);
        return object == null ? null : this.toLocalDateTime(object);
    }

    @Override
    public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Timestamp sqlTimestamp = cs.getTimestamp(columnIndex);
        return sqlTimestamp != null ? this.toLocalDateTime(sqlTimestamp.getTime()) : null;
    }

    private long toTimeMillis(LocalDateTime dateTime) {
        return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    private LocalDateTime toLocalDateTime(long timeMillis) {
        return new Date(timeMillis).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    private LocalDateTime toLocalDateTime(Object object) {
        if (object instanceof LocalDateTime) {
            return (LocalDateTime) object;
        } else if (object instanceof java.sql.Date) {
            java.sql.Date date = (java.sql.Date) object;
            return this.toLocalDateTime(date.getTime());
        } else if (object instanceof java.sql.Timestamp) {
            Timestamp sqlTimestamp = (Timestamp) object;
            return this.toLocalDateTime(sqlTimestamp.getTime());
        } else {
            System.out.println("实际类型是:" + object.getClass().getName());
            return null;
        }
    }
}

这样就不会报错了,如果有问题请评论!

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型
Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型
Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型
Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型。内存中的数据模型可以是任意数据结构或对象模型,存储数据的类型可以是XML,二进制流,关系模型等 ORM:在持久化对象上执行基本的增、删、改、查操作 使用Mybatis的步骤 1、 加载数据库驱动 2、 创建并获取数据库链接 3、 创建jdbc statement对象 4、 设置sql语句 5、 设置sql语句中的参数(使用preparedStatement) 6、 通过statement执行sql并获取结果 7、 对sql执行结果进行解析处理 8、 释放资源(resultSet、preparedstatement、connection)Spring MVC简介 基于java的实现MVC设计模式的请求驱动类型的轻量级Web框架,通过注解,无需实现任何接口,处理请求,支持restful。 三层结构:表现层、业务层、持久层 设计模式:Model(模型)、View(视图)、Controller(控制器) Mybatis框架是一个基于ORM的持久化框架,Mybatis框架不是一个完整的ORM实现,而是半自动化的ORM实现。Mybatis框架的主要特点是SQL映射器机制 持久化:就是将内存中有用的数据以某种技术保存起来,并且可以再次取出来应用。也就是说,可以将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子休。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值