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字段,当然会导致条件不匹配,查询结果为空
在这里插入图片描述

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

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

相关文章

零基础学Java第二十二天之IO流之内存流,打印流,随机流

IO流之内存流,打印流,随机流 1、内存流 1、理解 内存流"(Memory Stream)在计算机编程中通常指的是一种特殊的数据流,它在内存中存储和操作数据,而不是在外部存储(如硬盘、网络等&#xf…

申请轻纺行业工程设计资乙级对企业有什么要求

注册资金:企业的注册资金应至少达到三百万,这是衡量企业经济实力和承担风险能力的重要指标。独立法人资格:企业应具备独立的法人资格,能够独立承担民事责任,并具备相应的经营自主权。专业技术人员配备:企业…

前端框架选择指南:React vs Vue vs Angular

选择前端框架时,React、Vue 和 Angular 都是流行的选择,各有优缺点。我们可以从各个维度进行比较和选择: React 核心理念: 组件化开发,专注于视图层。学习曲线: 相对平缓,因为重点在于JSX和组…

免费的八字软件

无敌八字排盘软件完全免费使用,即使用不需要付费且无任何限制。同时推出手机版电脑版,两版本数据互通互用,即电脑版的数据可以备份到手机版上导入,手机版的数据也可以备份到电脑版上恢复导入,方便手机和电脑共用的朋友…

Golang实现递归复制文件夹

代码 package zdpgo_fileimport ("errors""os""path/filepath""strings" )// CopyDir 复制文件夹 // param srcPath 源文件夹 // param desPath 目标文件夹 // return error 错误信息 func CopyDir(srcPath, desPath string) error {…

在Java中实现泛型(Generics)的深入解析

在Java中,泛型(Generics)是一个强大的工具,它允许我们在编译时定义类型参数,使代码更加灵活、可重用和类型安全。下面,我将从技术难点、面试官关注点、回答吸引力以及代码举例四个方面,详细解析…

Android-自定义三角形评分控件

效果图 序言 在移动应用开发中,显示数据的方式多种多样,直观的图形展示常常能带给用户更好的体验。本文将介绍如何使用Flutter创建一个自定义三角形纬度评分控件,该控件可以通过动画展示评分的变化,让应用界面更加生动。 实现思…

转行3年涨薪300%,我总结了一套产品经理快速入门指南!

想转行的产品小白,初期一定会遇到这个问题——我要如何 0 基础转行产品经理? 要想 0 基础快速转行产品经理,我通过个人实践总结了 5 个关键点,可以参考。 一、熟悉产品经理的工作全流程 转行的产品小白,首先要建立产…

【刷题日记】最长连续序列

题目描述 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题 实现思路 核心要素两点: 1、当前元素的前驱是否在这个数组中&a…

ABtest假设检验知识|配对检验|比率检验|单向表-列联表检验

文章目录 1 假设检验基础2 一般假设检验2.1 假设检验包2.2 sample - 点击转化率2.2.1 问题描述2.2.2 实验设计2.2.3 数据处理2.2.4 方差齐性检验2.2.5 假设检验2.2.6 结果分析 3 检验两个均值的差:配对3.1 大样本检验3.1.1 单侧检验3.1.2 双侧检验 3.2 小样本检验3.…

【大模型】(记一面试题)使用Streamlit和Ollama构建PDF文件处理与聊天机器人应用

【大模型】(记一面试题)使用Streamlit和Ollama构建PDF文件处理与聊天机器人应用 我在找工作的过程中,遇到一个面试题:搭建一个简易的利用大型 LLM 和 RAG 来实现用户与PDF文件的自然语言交互。 参考链接:https://medium.com/the-ai-forum/ra…

深入理解软件测试:单元测试、集成测试与系统测试

软件测试是软件开发过程中至关重要的一环,旨在确保软件产品的质量和可靠性。根据测试的范围和目标,软件测试可以分为不同的层次和类型,其中最常见的包括单元测试、集成测试和系统测试。下面详细介绍这三种测试类型。 ### 1. 单元测试&#x…

【Python】—— 高阶函数

目录 (一)体验高阶函数 (二)内置高阶函数 2.1 map() 2.2 reduce() 2.3 filter() Python中的高阶函数是指那些接受函数作为参数,或者返回函数作为结果的函数。这种特性让Python的函数编程能力非常强大&…

三生随记——关于工地的恐怖故事

夜色中,月光斑驳地洒落在那片荒凉的工地。高耸的钢筋骨架如同巨大的怪兽,在黑暗中矗立着,散发着令人不安的气息。这里曾是城市的繁华之地,但如今却成了一片废墟,充满了无尽的恐怖和神秘。 工地四周被铁丝网围了起来&am…

Flutter 中的 GlowingOverscrollIndicator 小部件:全面指南

Flutter 中的 GlowingOverscrollIndicator 小部件:全面指南 Flutter 的 GlowingOverscrollIndicator 是一个视觉效果引人注目的组件,用于在列表或网格滚动超出其内容大小时提供视觉反馈。这种组件通常以发光效果指示用户已经滚动到了末端或超出了内容区…

算法题1:电路开关(HW)

题目描述 实验室对一个设备进行通断测试,实验员可以操控开关进行通断,有两种情况: ps,图没记下来,凭印象画了类似的 初始时,3个开关的状态均为断开;现给定实验员操控记录的数组 records ,records[i] = [time, switchId],表示在时刻 time 更改了开关 switchId 的状态…

【大模型】 基于AI和全球化进程的权衡:开源大模型与闭源大模型

【大模型】 基于AI和全球化进程的权衡:开源大模型与闭源大模型 前言 实际上关于开源or闭源,一直以来都是颇有争议的话题,人们争执于数据的隐私性和共享性,到底哪一方能获得的收益更大。而对于开源与闭源哪个更好实际上也就是说是…

Nginx的satisfy指令_ 用途,使用场景及注意事项

什么是satisfy指令? Nginx的satisfy指令用于控制当请求符合多个访问控制条件时,如何对这些条件进行组合判断。具体来说,它决定了是在多个访问控制条件中,只要任意一个条件满足即可还是全部条件都必须满足。 用途与使用场景 sat…

深度学习500问——Chapter09:图像分割(5)

文章目录 9.12 DenseNet 9.13 图像分割的数据集 9.13.1 PASCAL VOC 9.13.2 MS COCO 9.13.3 Cityscapes 9.14 全景分割 9.12 DenseNet 这篇论文是CVPR2017年的最佳论文。 卷积神经网络结构的设计主要朝着两个方向发展,一个是更宽的网络(代表&#xff1a…

【算法例题】n元钱买n只鸡

题目描述&#xff1a;公鸡5元1只&#xff0c;母鸡3元1只&#xff0c;小鸡1元3只&#xff0c;问&#xff1a;n元钱买n只鸡&#xff0c;怎么买&#xff1f; 解题思路&#xff1a;这题要用枚举算法&#xff0c;枚举鸡的数量&#xff0c;代码如下&#xff1a; ​#include <bit…