IntelliJ IDEA 集成 ShardingSphere-JDBC 访问分库分表

背景

众所周知,IntelliJ IDEA 是 Java 领域常用的开发工具之一,IDEA Ultimate(旗舰版)或其他例如 DataGrip 等 Intellij 平台的工具都集成了对数据库的访问能力。

但是,对于做了分库分表的项目,直接使用 IDEA 连接数据库只能访问具体的库、表。假如开发测试过程中,需要执行一些不带分片条件的查询语句,直连数据库的话只能手动逐个库表查询。

要解决分库分表数据访问的问题,Apache ShardingSphere 还有 ShardingSphere-Proxy,可以通过 Proxy 实现开发测试过程中的分库分表数据访问。但 Proxy 毕竟是独立进程,部署需要额外的资源与操作。考虑到:

  • 部分项目只通过 ShardingSphere-JDBC 访问分库分表,没有引入 ShardingSphere-Proxy 的条件。
  • 测试环境没有可供 Proxy 部署的资源,每次开发测试使用 IDEA 时,还要再单独本地启动一个 Proxy,相对麻烦。

所以,我们能否直接把 ShardingSphere-JDBC 集成到 IDEA 的数据库工具中,在 IDEA 内直接用逻辑 SQL 访问数据?

步骤

打包 ShardingSphere-JDBC 并在 IDEA 新建自定义数据库驱动

本文 JAR 的打包可以参考:https://github.com/TeslaCN/shardingsphere-all-in-one

对于使用依赖管理的项目,JAR 数量的多少对于开发者来说相对透明,引入依赖改改 POM 文件即可。但如果需要集成 ShardingSphere 的项目没有 Maven 或 Gradle 依赖管理(甚至没有源码),引入 ShardingSphere 可能是一项麻烦的事情。

Apache ShardingSphere 是一个模块拆分非常细的项目。当你只把基本的 ShardingSphere-JDBC 引入项目,你会发现项目依赖 JAR 包瞬间多了 100+ org.apache.shardingsphere 开头的 JAR,且该数量不包含 ShardingSphere 的第三方依赖。

        <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc</artifactId><version>5.5.0</version><exclusions><exclusion><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-test-util</artifactId></exclusion></exclusions></dependency>

本质就是引入 ShardingSphere-JDBC 的所有依赖,通过 maven-shade-plugin 打包为单个 JAR,以便引入 IDEA。

Apache ShardingSphere 官方提供了 ShardingSphere-JDBC 二进制包 的下载,但该包内 仅包含了 ShardingSphere-JDBC 的 JAR,不包括所有第三方依赖 ,所以这个包的实际应用场景比较受限。

在这里插入图片描述

踩坑:报错 SPI 找不到实现类

当然,事情不会那么顺利。当我们把配置文件准备好,填写了正确的 ShardingSphere JDBC URL 后,测试连接发现报错找不到 SPI 实现类。

此处使用的是绝对路径指定配置文件,参考文档:

jdbc:shardingsphere:absolutepath:/home/wuweijie/dev/shardingsphere/config-sharding.yaml

在这里插入图片描述
打开 IDEA 日志,发现如下报错。

2024-08-11 21:50:38,554 [22072396]   WARN - #c.i.d.d.BaseDatabaseErrorHandler$UnknownErrorInfo - SPI-00001: No implementation class load from SPI 'org.apache.shardingsphere.infra.url.spi.ShardingSphereURLLoader' with type 'absolutepath:'.
org.apache.shardingsphere.infra.spi.exception.ServiceProviderNotFoundException: SPI-00001: No implementation class load from SPI 'org.apache.shardingsphere.infra.url.spi.ShardingSphereURLLoader' with type 'absolutepath:'.at org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader.lambda$getService$1(TypedSPILoader.java:110)at java.base/java.util.Optional.orElseThrow(Optional.java:403)at org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader.lambda$getService$2(TypedSPILoader.java:110)at java.base/java.util.Optional.orElseGet(Optional.java:364)at org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader.getService(TypedSPILoader.java:110)at org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader.getService(TypedSPILoader.java:97)at org.apache.shardingsphere.infra.url.core.ShardingSphereURLLoadEngine.<init>(ShardingSphereURLLoadEngine.java:39)at org.apache.shardingsphere.driver.jdbc.core.driver.DriverDataSourceCache.createDataSource(DriverDataSourceCache.java:56)at org.apache.shardingsphere.driver.jdbc.core.driver.DriverDataSourceCache.lambda$get$0(DriverDataSourceCache.java:50)at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)at org.apache.shardingsphere.driver.jdbc.core.driver.DriverDataSourceCache.get(DriverDataSourceCache.java:50)at org.apache.shardingsphere.driver.ShardingSphereDriver.connect(ShardingSphereDriver.java:71)at com.intellij.database.remote.jdbc.helpers.JdbcHelperImpl.connect(JdbcHelperImpl.java:790)at com.intellij.database.remote.jdbc.impl.RemoteDriverImpl.connect(RemoteDriverImpl.java:153)

难道是我打的 shade 包出问题了?
检查 JAR 包发现,SPI 的 services 文件和 absolutepath 的 class 文件都在。
在这里插入图片描述
在这里插入图片描述

于是搜了下 IDEA 加载 SPI 的问题,发现 IDEA 的插件也有无法加载 SPI 实现类的问题:ServiceLoader issues and locating folders inside the plugin

大致意思:SPI 不生效是因为 IDEA 使用了独立的类加载器加载插件导致的。

那这个问题也不是完全无解,数据库插件的 Expert options 中可以去除勾选 Isolate class path

在这里插入图片描述
去除勾选后 SPI 找不到实现类的问题就解决了。

小结:当项目集成 ShardingSphere 后报错找不到 SPI 时,关注一下与类加载器是否有关系。

再踩坑:报错 StackOverflowError

在这里插入图片描述
查 IDEA 日志发现,爆栈的错误信息如下,明显是日志实现发生了问题。

Caused by: java.lang.StackOverflowErrorat org.slf4j.jul.JDK14LoggerAdapter.log(JDK14LoggerAdapter.java:167)at org.slf4j.bridge.SLF4JBridgeHandler.callLocationAwareLogger(SLF4JBridgeHandler.java:221)at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:303)at java.logging/java.util.logging.Logger.log(Logger.java:983)at org.slf4j.jul.JDK14LoggerAdapter.innerNormalizedLoggingCallHandler(JDK14LoggerAdapter.java:156)at org.slf4j.jul.JDK14LoggerAdapter.log(JDK14LoggerAdapter.java:172)at org.slf4j.bridge.SLF4JBridgeHandler.callLocationAwareLogger(SLF4JBridgeHandler.java:221)at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:303)at java.logging/java.util.logging.Logger.log(Logger.java:983)at org.slf4j.jul.JDK14LoggerAdapter.innerNormalizedLoggingCallHandler(JDK14LoggerAdapter.java:156)at org.slf4j.jul.JDK14LoggerAdapter.log(JDK14LoggerAdapter.java:172)at org.slf4j.bridge.SLF4JBridgeHandler.callLocationAwareLogger(SLF4JBridgeHandler.java:221)at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:303)at java.logging/java.util.logging.Logger.log(Logger.java:983)

此时笔者想起,IDEA 自从 2022.1 版本起使用 java.util.logging 代替第三方日志实现:Removing log4j from the IntelliJ Platform

ShardingSphere 内部使用的 Guava EventBus 默认以 java.util.logging 作为日志输出框架,为了将 EventBus 日志与 ShardingSphere-Proxy 的日志输出统一,ShardingSphere 通过 jul-to-slf4j 将日志输出统一到 slf4j 了。由于笔者当时没有考虑到与 ShardingSphere-JDBC 集成的项目可能会把 java.util.logging 作为日志输出框架,jul-to-slf4j 直接应用到了 infra 类上面(对 JDBC 与 Proxy 都生效)。

Bridges error logs which printed by ShardingSphereEventBus to slf4j #17541

由此引发的问题:假如集成 ShardingSphere 的项目本身使用 java.util.logging 作为日志框架,集成就会发生日志实现冲突,可能发生的问题包括但不限于本文中的 StackOverflowError

笔者针对该问题提交的 PR 已被合并,将随 ShardingSphere 下一版本发布:
Make jul-to-slf4j work in ShardingSphere-Proxy only #32347

集成初步完成

Test Connection 操作成功后,就可以在 Console 中执行逻辑 SQL 了。
在这里插入图片描述

打开 IDEA 的日志,可以在日志中找到逻辑 SQL 与实际执行的物理 SQL。
在这里插入图片描述

之所以说集成是“初步”完成的原因,是 ShardingSphere-JDBC 对元数据查询的支持有限,可能没有办法像直连数据库一样在 IDEA 中正确展示已有的数据库和表。

后续笔者会进一步研究 IDEA 加载数据源的库表的实现,尝试让 IDEA 能够加载 ShardingSphere-JDBC 的逻辑库与逻辑表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/403757.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

消防隐患在线小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;消防隐患举报管理&#xff0c;消防隐患分类管理&#xff0c;统计分类管理&#xff0c;处理结果管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;我…

学习笔记 韩顺平 零基础30天学会Java(2024.8.18)

P514 Vector源码解读 P515 双向链表模拟 LinkedList的添加和删除可以通过改变节点的指向完成 遍历的时候&#xff0c;如果要重新遍历&#xff0c;要把指针调回到最前面或者最后面&#xff0c;才能重新全部遍历一次 插入的时候&#xff0c;插入对象的next和pre都要操作&#xff…

探索tailwindcss多主题切换

现在的多主题切换基本上都是用的 css 变量的形式, 而tailwindcss也支持 css 变量定义主题的方式 至于为什么用 tailwindcss变量, 还是因为 tailwind 写类名提示比较方便, 也不需要再在css或者style中去一个个var的形式去写变量了 这里我在assets/style/theme文件夹中创建了三个…

音视频开发

通过多线程分别获取高分辨率(1920 * 1080)和低分辨率(1280 * 720) 初始化VI模块 初始化HIGH VENC模块 初始化LOW VENC模块 初始化RGA模块 绑定 VI和HIGH VENC 绑定 VI和RGA 创建线程 HIGH VENC处理 RGA处理 LOW VENC处理 销毁 QP原理的讲解 QP参数调节&#xff0c;指的是量化…

【后端记录】修复MySql的错误修改的数据记录【binlog修复】

前言 今天入门后端的时候&#xff0c;不小心改了非预期的数据&#xff0c;因为还没学到事务&#xff0c;所以恢复数据还比较麻烦&#xff0c;站在巨人的肩膀上还是解决了&#xff0c;原文连接在下面 https://blog.csdn.net/qq_42874315/article/details/140480570 解决办法 原…

【自动驾驶】控制算法(二)三大坐标系与车辆运动学模型

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

第37讲:Cephfs文件系统的正确使用姿势

文章目录 1.Cephfs文件系统简介2.Cephfs文件系统细节介绍2.1.Cephfs文件系统多客户端隔离挂载2.2.Ceph集群中多个Cephfs如何单独使用 3.挂载多个Cephfs文件系统4.Cephfs文件系统多客户端隔离挂载实战4.1.创建一个Cephfs文件系统4.2.将Cephfs文件系统挂载到本地路径4.3.在Cephfs…

java:IDEA修改java版本的几个不同的地方

文章目录 项目JDK设置&#xff08;Project SDK&#xff09;项目模块级JDK设置&#xff08;Module SDK&#xff09;IDE级别的JDK设置Maven配置文件编译器&#xff08;Java Compiler&#xff09;构建工具配置文件&#xff08;如build.gradle或pom.xml&#xff09;.idea/misc.xml文…

Chrome快捷键提高效率

浏览效率提高快捷建 快速切换标签页 Ctrl 数字&#xff08;1或者2&#xff09;&#xff0c;标签页数字从左到右为顺序&#xff0c;1开始。快速切换标签页。 Ctrl1 到 Ctrl8 切换到标签栏中指定位置编号所对应的标签页 Ctrl9切换到最后一个标签页 CtrlTab 或 CtrlPgDown 切…

EasyCVR视频汇聚平台构建远程安防监控:5大亮点解析,助力安防无死角

随着科技的飞速发展&#xff0c;远程安防监控系统已经成为现代社会中不可或缺的一部分&#xff0c;无论是在小区、公共场所还是工业领域&#xff0c;安防监控都发挥着至关重要的作用。而EasyCVR作为一款功能强大的视频监控综合管理平台&#xff0c;其在构建远程安防监控系统方面…

英伟达开源 Nemotron-4-4B:小型模型,大能量

前沿科技速递&#x1f680; 在人工智能领域&#xff0c;语言模型已经成为推动自然语言处理&#xff08;NLP&#xff09;进步的关键力量。然而&#xff0c;随着模型规模的不断扩大&#xff0c;训练和部署这些大型语言模型&#xff08;LLM&#xff09;的资源成本也在急剧增加。为…

WUP-MY-LABEL-PRINTER 旻佑热敏打印机标签打印uniapp插件使用说明

插件地址&#xff1a;WUP-MY-LABEL-PRINTER 旻佑热敏打印机标签打印安卓库 简介 本插件主要用于旻佑热敏打印机打印标签&#xff0c;不支持票据打印。适用于旻佑的各型支持标签打印的热敏打印机。本插件开发时使用的打印机型号为MY-805嵌入式面板打印机&#xff0c;其他型号请…

uni-app--》打造个性化壁纸预览应用平台(二)

&#x1f3d9;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名前端工程师 &#x1f304;个人主页&#xff1a;亦世凡华、 &#x1f306;系列专栏&#xff1a;uni-app &#x1f307;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

深度学习的量化和剪枝

一&#xff1a;背景 如果要将深度学习的AI模型部署到受限设备&#xff08;FPGA&#xff09;上&#xff0c;往往需要更小的存储需求和最低的计算复杂度。当然&#xff0c;还得保持一定的性能&#xff08;下降在能够接受的范围&#xff09;。受限设备资源的环境&#xff0c;一般是…

数据结构与算法--插入排序与选择排序

文章目录 回顾提要排序基本概念排序的分类排序算法的稳定性排序算法的性能指标内排序 排序方法直接插入排序直接插入排序的要点直接插入排序的实现直接插入排序性能分析直接插入排序的适用情景 简单选择排序简单选择排序的要点简单选择排序的执行过程简单选择排序的实现简单选择…

分布式锁:Mysql实现,Redis实现,Zookeeper实现

目录 前置知识 Mysql实现分布式锁 1.get_lock函数 Java代码实现&#xff1a; 2.for update尾缀 Java代码实现&#xff1a; 3.自己定义锁表 Java代码实现&#xff1a; 4.时间戳列实现乐观锁 Java代码实现&#xff1a; Redis实现分布式锁 Zookeeper实现分布式锁&#…

完整搭建windows下mysql8.0源码编译调试环境!

背景&#xff1a; 前段时间一直在看mysql相关的博客&#xff0c;所以对源码起了浓厚的兴趣&#xff0c;所以尝试通过vmware和vscode在windosw环境中搭建一套编译调试的环境~ 看了一下网上的搭建教程基本杂乱无章&#xff0c;想要从零跟着搭建出一个完善的调试环境也不是易事&…

Leetcode3232. 判断是否可以赢得数字游戏

Every day a Leetcode 题目来源&#xff1a;3232. 判断是否可以赢得数字游戏 解法1&#xff1a;3232. 判断是否可以赢得数字游戏 用一个 sum1 统计个位数的和&#xff0c;sum2 统计十位数的和。 只要 sum1 和 sum2 不相等&#xff0c;Alice 拿大的就能赢得这场游戏。 代码…

Maven的依赖范围

依赖的jar包&#xff0c;默认情况下&#xff0c;可以在任何地方使用&#xff0c;可以通过scope来设置作用范围 作用范围&#xff1a; 主程序范围有效&#xff08;main文件夹范围内&#xff09;测试程序范围有效&#xff08;test文件夹范围内&#xff09;是否参与打包运行&…

一次日志记录中使用fastjson涉及到ByteBuffer的教训

背景 目前本人在公司负责的模块中&#xff0c;有一个模块是负责数据同步的&#xff0c;主要是将我们数据产线使用的 AWS Dynamodb 同步的我们的测试QA 的环境的 MongoDB 的库中&#xff0c;去年开始也提供了使用 EMR 批量同步的功能&#xff0c;但是有时候业务也需要少量的数据…