mysql驱动版本变更导致查询数据结果一直是空

1 引言

最近接手了一个已离职同事的java项目,这个项目中原来使用了自己的mysql驱动版本,并未使用公司公共依赖中的版本号。我想为了统一版本号,就将当前项目中pom文件中mysql的版本号verson给去除了。没怎么自测,就直接发到测试环境了,结果没多久就有测试人员告诉了说,有接口报错。
其主逻辑sql如下

SELECT * FROM rule_category where `name`='企业资质' and parent_id=0;

后面发现不止这个接口查询结果为空,其他好几个接口的查询结果都未空。我用同样的sql语句在navicat中能查出结果,我开始怀疑我是不是连错数据库了,是不是连接到开发环境中的数据库。我使用Environment#getProperty("spring.datasource.url")获取到的数据库url可以确定是测试环境。后面进一步发现这些接口中都有中文查询条件,我开始怀疑是字符集的问题。回到刚才的数据库连接URL,其格式是jdbc:mysql://xxhost:3306/rule_engine?serverTimezone=GMT%2B8 ,这个URL明显没有指定字符集编码,我在这个url上加上characterEncoding=UTF8参数,本地重新启动项目,在swagger中调用接口,最终预期数据正常返回。
现在问题是解决了,大致应该是不同版本的数据库驱动其默认字符集编码不同。这个项目的原始数据库驱动版本是8.0.32 ,而我修改后继承了父依赖的版本号8.0.21

先看mysql-connector 8.0.32

com.mysql.cj.NativeCharsetSettings#NativeCharsetSettings 是mysql驱动 8.0.32 中的一个字符集配置相关的类,
在这里插入图片描述
上面的characterEncoding字段的description的大致意思是在未主动配字符集编码时,8.0.25及以下版本的数据库驱动会使用mysql服务器的默认编码,而在8.0.26及以上版本的数据库驱动会使用utf8mb4

8.0.23的mysql驱动在建立socket连接之前,会调用com.mysql.cj.NativeCharsetSettings#configurePreHandshake方法
在这里插入图片描述
sessionCollationIndex为null,先给它赋值为utf8mb4_0900_ai_ci字符集对应的index,在然后根据数据库服务器版本号重新进一步赋值,我们公司数据库的版本5.7.39,此版本号小于下图中的8.0.1会被赋值为 utf8mb4_general_ci对应的index。所以可以看出8.0.23版本的mysql驱动的默认字符集编码是utfmb8
在这里插入图片描述

再看下面的connectionCollation的说明,这个属性是字符排序规则,这里还提到了字符编码。如果connectionCollation是latin1_swedish_ci,那么mysql的字符集就是latin1 ,而映射到java语言就是windows-1252字符集,如果characterEncoding没有被设置,那么就会使用windows-1252字符集。这里最后几句话再次说明了:characterEncoding没有被主动设置时,在8.0.25以下版本,使用数据库server端的默认字符编码,而在8.0.26及以上版本,直接使用utf8mb4编码。
在这里插入图片描述

再看mysql-connector 8.0.21

类似地此版本的驱动在建立正式的socket连接之前,会调用com.mysql.cj.NativeCharsetSettings#configurePreHandshake方法
在这里插入图片描述
configurePreHandshake又会调用 readServerCapabilities方法,readServerCapabilities方法就是解析mysql server返回的第一数据报文,这个数据报文中包含了mysql server的通信协议版本、数据库版、默认字符集等信息。readServerCapabilities方法
的核心的逻辑在serverCapabilities.setInitialHandshakePacket(buf)这行代码
在这里插入图片描述
在这里插入图片描述
从下图可以看出 mysql server的默认字符集编码是latin1,对应的java字符集是windows-1252
在这里插入图片描述
为了验证mysql server的默认字符集是否是latin1, 可以在navicat执行一个这个SQL脚本

show VARIABLES like '%set_database';

下图显示其字符集编码果然是latin1
在这里插入图片描述
而数据库的表字段rule_category.name是utf8mb4,在8.0.21版本的驱动使用mysql server默认的latin1编码去查询utf8mb4编码的 name字段,当然会导致条件不匹配,查询结果为空
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【网络】为什么udp协议报头有长度字段,而tcp没有

引言: 在网络通信中,UDP(用户数据报协议)和TCP(传输控制协议)是两种常用的传输层协议。它们在设计和功能上有一些不同之处,其中之一就是报头中的长度字段。本文将深入探讨UDP和TCP协议中长度字…

解释JAVA语言中关于方法的重载

在JAVA语言中,方法的重载指的是在同一个类中可以存在多个同名方法,但它们的参数列表不同。具体来说,重载的方法必须满足以下至少一条条件: 1. 参数个数不同。 2. 参数类型不同。 3. 参数顺序不同。 当调用一个重载方法时,编译器…

2024 电工杯(B题)数学建模完整思路+完整代码全解全析

你是否在寻找数学建模比赛的突破点?数学建模进阶思路! 作为经验丰富的数学建模团队,我们将为你带来2024电工杯数学建模竞赛(B题)的全面解析。这个解决方案包不仅包括完整的代码实现,还有详尽的建模过程和解…

用队列实现栈,用栈实现队列

有两个地方会讨论到栈,一个是程序运行的栈空间,一个是数据结构中的栈,本文中讨论的是后者。 栈是一个先入后出,后入先出的数据结构,只能操作栈顶。栈有两个操作,push 和 pop,push 是向将数据压…

CentOS7 部署单机版 elasticsearch

一、环境准备 1、准备一台系统为CentOS7的服务器 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) 2、创建新用户,用于elasticsearch服务 # elastic不允许使用root账号启动服务 [rootlocalhost ~]# useradd elastic [rootlo…

【全开源】沃德商协会管理系统源码(FastAdmin+ThinkPHP+Uniapp)

一款基于FastAdminThinkPHPUniapp开发的商协会系统,新一代数字化商协会运营管理系统,以“智慧化会员体系、智敏化内容运营、智能化活动构建”三大板块为基点,实施功能全场景覆盖,一站式解决商协会需求壁垒,有效快速建立…

PostgreSQL事务基础理解

PostgreSQL事务 事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。数据库事务通常包含一个序列对数据库的读和写操作,主要是包含以下两个目的: 为数据库操作序列提供一个从失败中恢复到正常状态的方法&#…

1.Redis之初识Redis分布式系统

1.初识Redis 1.1 官网 Redis中文网 Redis 教程 | 菜鸟教程 (runoob.com) 1.2 解释 在内存中存储数据 定义变量,不就是在内存中存储数据嘛?? Redis 是在分布式系统(进程的隔离性:Redis 就是基于网络,可以把自己内存中的变量给别的进程…

【Linux】简单模拟C语言文件标准库FILE

👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…

Java进阶学习笔记10——子类构造器

子类构造器的特点: 子类的全部构造器,都会先调用父类的构造器,再执行自己。 子类会继承父类的数据,可能还会使用父类的数据。所以,子类初始化之前,一定先要完成父类数据的初始化,原因在于&…

【Java面试】一、Redis篇(上)

文章目录 0、准备1、缓存穿透:不存在的key2、缓存击穿:热点key过期3、缓存雪崩:大批key同时过期4、双写一致性4.1 要求高一致性4.2 允许一定的一致延迟 5、面试 0、准备 Redis相关概览: 以简历上所列的项目为切入点,展…

C语言/数据结构——队列的实现

一.前言 今天我们来聊一聊数据结构的一部分——队列。今天我们主要涉及队列的基本概念结构,以及队列的基本实现。 二.正文 1.1队列 1.12队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表&#xf…

ue5 中ps使用记录贴

一、快捷键记录 放大图形 ctrlalt空格 放大图形 缩小视口 ctrl空格 ctrlD 取消选区 ctrlt缩小文字 w魔棒工具 选择魔棒的时候把容差打开的多一点 二、案例 移动文字 在相应的图层选择 移动文字 修改图片里的颜色 在通道里拷贝红色通道,复制红色通道粘贴给正常图…

【ELK日志收集过程】

文章目录 为什么要使用ELK收集日志ELK具体应用场景ELK日志收集的流程 为什么要使用ELK收集日志 使用 ELK(Elasticsearch, Logstash, Kibana)进行日志收集和分析有多种原因。ELK 堆栈提供了强大、灵活且可扩展的工具集,能够满足现代 IT 系统对…

CIM模型

CIM 是 Esri 制图信息模型。 它是一个地图内容规范,用于记录在保存、读取、引用或打开时如何永久保留描述不同项目组件的信息。 该规范以 JSON 表示,适用于 ArcGIS 应用程序和 API 中的地图、场景、布局、图层、符号和样式。 CIM 不仅限于制图设置。 要了解属性的组织方式以及…

使用vue3实现右侧瀑布流滑动时左侧菜单的固定与取消固定

实现效果 实现方法 下面展示的为关键代码,想要查看完整流程及代码可参考https://blog.csdn.net/weixin_43312391/article/details/139197550 isMenuBarFixed为控制左侧菜单是否固定的参数 // 监听滚动事件 const handleScroll () > {const scrollTopThreshol…

数据库系统基础知识

一、基本概念 二、数据库三级模式两级映像 三、数据库的分析与设计过程 四、数据模型 五、关系代数 六、数据库完整性约束 七、关系型数据库SQL简介 八、关系数据库的规范化 九、数据库的控制功能 十、数据仓库与数据挖掘基础 十一、大数据基本概念 数据库基本概念 1、数据库…

Spring 对于事务上的应用的详细说明

1. Spring 对于事务上的应用的详细说明 文章目录 1. Spring 对于事务上的应用的详细说明每博一文案2. 事务概述3. 引入事务场景3.1 第一步:准备数据库表3.2 第二步:创建包结构3.3 第三步:准备对应数据库映射的 Bean 类3.4 第四步:…

hcia datacom学习(10):交换机基础

1.二层交换机工作原理 1.1交换机的5种行为 查看mac地址表的命令为 dis mac-address *一个MAC只能关联在一个接口上,一个接口上可以学习多个MAC *mac地址漂移:mac表中,mac地址的出接口从一个端口变为另一个端口的现象。 造成mac漂移的原因…

操作系统实验四 (综合实验)设计简单的Shell程序

前言 因为是一年前的实验,很多细节还有知识点我都已经遗忘了,但我还是尽可能地把各个细节讲清楚,请见谅。 1.实验目的 综合利用进程控制的相关知识,结合对shell功能的和进程间通信手段的认知,编写简易shell程序&…