给分库分表的 ShardingSphere 提了个PR,这Bug居然改了
说来惭愧干了 10 来年程序员还没有给开源做过任何贡献以前只知道嘎嘎写出了问题嘎嘎改从来没想过提个 PR 去修复他最近碰到个问题发现挺简单的就随手提了个 PR 过去。问题问题挺简单的就是在使用 mybatis 和 ShardingSphere 的时候有人在 model 类使用了OffsetDateTime这个时间类型发现会报错。Caused by: java.lang.ClassCastException: class java.sql.Timestamp cannot be cast to class java.time.OffsetDateTime (java.sql.Timestamp is in module java.sql of loader platform; java.time.OffsetDateTime is in module java.base of loader bootstrap) at org.apache.ibatis.type.OffsetDateTimeTypeHandler.getNullableResult(OffsetDateTimeTypeHandler.java:38) at org.apache.ibatis.type.OffsetDateTimeTypeHandler.getNullableResult(OffsetDateTimeTypeHandler.java:28) at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85) ... 99 more这就是一个简单的类型转换的异常于是跟着源码看了下先看到BaseTypeHandler#getResult这个方法实际上就是根据列名返回查询结果。根据调用关系找到了OffsetDateTimeTypeHandler实现类。发现最终会调用rs.getObject()这个方法那么其实这个方法会最终走到由 ShardingSphere 实现的getObject方法中。看到这里的时候其实已经明白了为啥会报错了Shardingsphere 只判断了几个LocalDateTime等类型对于这个比较特殊的时间类型没有处理最终会转换成 Timestamp 然后强转就报错了。最后调用到ResultSetUtil#convertTimestampValue方法可以看到确实是这样哈。那如果修改源码的话其实很简单了getObject判断多加一个convertTimestampValue再加一个就这样很简单啊。Override public T T getObject(final int columnIndex, final ClassT type) throws SQLException { if (BigInteger.class.equals(type)) { return (T) BigInteger.valueOf(getLong(columnIndex)); } else if (Blob.class.equals(type)) { return (T) getBlob(columnIndex); } else if (Clob.class.equals(type)) { return (T) getClob(columnIndex); } else if (LocalDateTime.class.equals(type) || LocalDate.class.equals(type) || LocalTime.class.equals(type) || OffsetDateTime.class.equals(type)) { return (T) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Timestamp.class), type); } else { return (T) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, type), type); } } private static Object convertTimestampValue(final Object value, final Class? convertType) { Timestamp timestamp (Timestamp) value; if (LocalDateTime.class.equals(convertType)) { return timestamp.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); } if (LocalDate.class.equals(convertType)) { return timestamp.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); } if (LocalTime.class.equals(convertType)) { return timestamp.toInstant().atZone(ZoneId.systemDefault()).toLocalTime(); } if (OffsetDateTime.class.equals(convertType)) { return timestamp.toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime(); } return value; }修复最开始我其实并不想改源码我在想其他的实现方案搜索后发现引入一个包就可以解决也就是 mybatis 的 JSR310 规范。dependency groupIdorg.mybatis/groupId artifactIdmybatis-typehandlers-jsr310/artifactId version1.0.1/version /dependency他为什么能解决这个问题我看了下他的包里面的代码这不就是加了个 TypeHandler 自己处理了嘛。再去看了下OffsetDateTimeTypeHandler的实现其实就是自己就解决了直接给返回OffsetDateTime根本不会走到 ShardingSphere 的逻辑里面去这也就是他能解决这个问题的原因了。当然如果不想那么麻烦引入一个包也可以单独把他拎出来自己去指定一下这个很简单就不多说了。提PR于是我想这事情这么简单我不如提个 PR 给官方吧这里教下大家怎么提 PR 。因为不是咱们的项目是没法 push 代码的所以进入到项目然后forkfork 好了以后直接把项目 clone 下来然后执行命令。git remote add upstream https://github.com/apache/shardingsphere.git通过命令我们可以看到成功了这样就 OK了然后正常拉分支写代码吧。写完之后正常去我们的项目界面提交 PR然后就可以了。麻烦当然过程并没有这么顺利虽然说只是很简单的修改。首先这个校验就给我提示错误了第一点叫我不要用*号去引用。这个其实是IDEA的锅如果引用同一个包下类过多的话会自动帮我们转成星号这个我们可以在Editor-Code Style-Java然后找到 Imports 下的这两个选项把他们都改成 99 就可以了防止他自动给我们改成星号。还有一些其他的比如 if 后面没跟空格之类的这是我忘记格式化了然后大佬回复觉得看不下去这代码太恶心了说我们是不是可以用java.time.temporal.TemporalAccessor来判断不然这么多时间类型搞个毛线呢。然后我就翻译了一段英文我也不知道大佬看没看懂我告诉他这个不好整啊你看这个接口啊很多乱七八糟的类实现了他实际上我觉得我们覆盖常用的一些就行了其他的特殊时间类型让他们自己用 TypeHandler 处理吧。大佬说嗯当然没办法判断这个接口那我们也没辙了我说那不可就是嘛。其实还有很多时间类型他都会报错的最好的办法这个都抽象出来和Mybatis单独用实现类不过那样的话就得大工作了我太懒了就这样。。。。最后要看了一下大佬们已经把这个bug Fixed了我这也算是为开源做过贡献的人了身上光环锃亮

相关新闻

32 图 | 玩转 Spring Cloud Gateway + JWT 登录认证

32 图 | 玩转 Spring Cloud Gateway + JWT 登录认证

前言 上篇我已经讲解了 Spring Cloud 的原理和实战,这次就要结合 JWT 来实现登录认证的功能了。 通过本文你会掌握以下知识点: 如何用认证服务做登录认证。 如何生成 JWT 令牌(Token) 如何用 Gateway 对 Token 验证。 Gateway 如何从 Token 中拿到用…

2026/7/5 17:22:33 阅读更多 →
6000 字 | 16 图,吃透 Spring Cloud Gateway 原理

6000 字 | 16 图,吃透 Spring Cloud Gateway 原理

本篇给大家带来的是微服务框架中非常重要的一个组件:API 网关。前言在 PassJava 项目中,我用到了 Spring Cloud Gateway 作为 API 网关,客户端的所有的请求都是先经过网关,然后再转发到会员微服务、题目微服务等。比如 API 网关和…

2026/7/5 7:38:30 阅读更多 →
OpenClaw火爆出圈!246K星!硬核拆解本地化AI助理架构,企业级Agent架构演进至17层!

OpenClaw火爆出圈!246K星!硬核拆解本地化AI助理架构,企业级Agent架构演进至17层!

最近的 AI 开发者圈子里,有一个项目以惊人的速度火爆出圈,它的 GitHub Star 数在短短一个月内飙升到了夸张的 246K,作为对比,沉淀了三年的头部低代码 AI 平台 Dify 目前是 130K 左右。 它就是经历了从 Clawdbot 到 Moltbot &#…

2026/5/17 8:33:03 阅读更多 →

最新新闻

叶兴阳双语音标,英语发音工具断层级天花板

叶兴阳双语音标,英语发音工具断层级天花板

功能向实测评价:叶兴阳双语音标,英语发音工具断层级天花板 深耕英语学习多年,试过市面各类音标教辅、发音软件、双语读物,唯有叶兴阳双语音标在功能性上做到全方位无短板,每一项核心功能都精准戳中自学、教学、精读全场…

2026/7/6 4:38:22 阅读更多 →
Python+OpenCV 4.8 与 Tesseract OCR 5.3 车牌识别方案对比评测

Python+OpenCV 4.8 与 Tesseract OCR 5.3 车牌识别方案对比评测

PythonOpenCV 4.8 与 Tesseract OCR 5.3 车牌识别方案深度评测车牌识别技术作为计算机视觉领域的重要应用,在智能交通、停车场管理等领域发挥着关键作用。本文将深入对比两种主流车牌识别方案:基于OpenCV 4.8的传统图像处理方案和基于Tesseract OCR 5.3的…

2026/7/6 4:38:22 阅读更多 →
3分钟掌握免费Android投屏神器:scrcpy终极使用指南

3分钟掌握免费Android投屏神器:scrcpy终极使用指南

3分钟掌握免费Android投屏神器:scrcpy终极使用指南 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy 还在为手机屏幕太小而烦恼?想要在电脑大屏幕上操作手机应用&…

2026/7/6 4:36:22 阅读更多 →
2026小提琴选购攻略!吃透三大核心参数,5款高口碑机型实测推荐

2026小提琴选购攻略!吃透三大核心参数,5款高口碑机型实测推荐

一、内行干货!新手购琴必懂的三大核心参数其实判断一把小提琴的好坏,无需钻研复杂专业术语,只要吃透板材、工艺、音色三大核心维度,再把控好尺寸与配件细节,就能精准筛选出优质机型,避开99%的购琴误区。板材…

2026/7/6 4:34:21 阅读更多 →
2026年同声传译软件免费额度实测对比,差距竟然这么大谁才好用?

2026年同声传译软件免费额度实测对比,差距竟然这么大谁才好用?

先说结论:这类工具怎么选 没有万能的同声传译软件,2026年实测下来五款主流工具的免费额度差距确实超出预期。针对知识付费用户消化付费课程、整理播客内容、巩固学习效果的核心需求,不同工具的适配性完全不同。不要盲目追大厂,不…

2026/7/6 4:32:21 阅读更多 →
压榨机器,Hack,设计极限强度的网络应用

压榨机器,Hack,设计极限强度的网络应用

在《对话网友 - TCP一万连接系统设计》文后回复中,短短的评论不足以说明问题,于是单独撰文解释。 对于一般的应用来说,操作系统足以对付,对于极限应用来说,操作系统往往就成了我们的障碍,这里的障碍有两个意…

2026/7/6 4:32:20 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻