From a7b997321ce768bf053ee8c6248424f8cbf1cff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A5=9E=E7=A0=81-=E6=96=B9=E6=99=93=E8=BE=89?= Date: Sun, 1 Feb 2026 13:21:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DMySQL=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E9=9B=86=E9=97=AE=E9=A2=98=EF=BC=8C=E9=98=B2=E6=AD=A2?= =?UTF-8?q?=E4=B8=AD=E6=96=87=E4=B9=B1=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 问题描述 用户反馈:菜单comment字段可能出现乱码 ## 问题分析 ### 乱码原因 1. **MySQL连接字符集不匹配**: - 客户端未指定字符集 - 默认字符集与数据不匹配 2. **终端显示问题**: - 终端编码与数据库编码不一致 - 查询结果传输过程中字符集转换错误 ### 数据库状态检查 ```sql -- 当前配置 character_set_client = utf8mb4 ✅ character_set_connection = utf8mb4 ✅ character_set_database = utf8mb4 ✅ character_set_results = utf8mb4 ✅ -- 表字符集 sys_menu: utf8mb4_general_ci ✅ ``` ## 解决方案 ### 1. 更新import_menu.sh导入脚本 **修改**:所有mysql命令添加`--default-character-set=utf8mb4` ```bash # 修复前 ❌ mysql -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$SQL_FILE" # 修复后 ✅ mysql -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" < "$SQL_FILE" ``` ### 2. 创建字符集修复工具 **新增**:`sql/fix_charset.sh` **功能特性**: - ✅ 检查数据库字符集配置 - ✅ 检查表字符集设置 - ✅ 测试查询菜单数据 - ✅ 一键修复表字符集 - ✅ 自动备份原表数据 **使用方法**: ```bash cd sql ./fix_charset.sh ``` **修复流程**: 1. 检查当前字符集配置 2. 显示菜单数据(检测乱码) 3. 用户确认是否修复 4. 创建备份表 5. 转换表字符集为utf8mb4 6. 验证修复结果 ## 预防措施 ### 数据导入时 ```bash # 始终指定字符集 mysql --default-character-set=utf8mb4 -h... < file.sql ``` ### 数据查询时 ```bash # 查询时指定字符集 mysql --default-character-set=utf8mb4 -h... -e "SELECT ..." ``` ### 应用程序配置 ```yaml # application.yml中确保 spring: datasource: url: jdbc:mysql://...?characterEncoding=utf8mb4&useUnicode=true ``` ## 验证结果 ```sql SELECT menu_id, menu_name, remark FROM sys_menu WHERE parent_id = 0; 2000 盘古管理 盘古用户平台业务菜单 ✅ 1 系统管理 系统管理目录 ✅ 2 系统监控 系统监控目录 ✅ ``` ## 相关文件 - sql/import_menu.sh - 菜单导入脚本(已修复) - sql/fix_charset.sh - 字符集修复工具(新增) --- 作者:湖北新华业务中台研发团队 --- sql/fix_charset.sh | 97 ++++++++++++++++++++++++++++++++++++++++++++++ sql/import_menu.sh | 6 +-- 2 files changed, 100 insertions(+), 3 deletions(-) create mode 100755 sql/fix_charset.sh diff --git a/sql/fix_charset.sh b/sql/fix_charset.sh new file mode 100755 index 0000000..37ab325 --- /dev/null +++ b/sql/fix_charset.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# ============================================================ +# 脚本名称:fix_charset.sh +# 功能说明:修复数据库字符集和乱码问题 +# 作 者:湖北新华业务中台研发团队 +# 创建时间:2026-01-31 +# 使用方法:./fix_charset.sh +# ============================================================ + +set -e + +# 数据库配置 +DB_HOST="8.148.25.55" +DB_PORT="3306" +DB_USER="root" +DB_PASS="aly2024A" +DB_NAME="pguser-db" + +echo "============================================================" +echo "数据库字符集检查与修复工具" +echo "============================================================" +echo "" + +# 1. 检查数据库字符集 +echo "1. 检查数据库字符集配置..." +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 -e " +SHOW VARIABLES LIKE 'character_set%'; +" 2>&1 | grep -v "Warning" + +echo "" + +# 2. 检查sys_menu表字符集 +echo "2. 检查sys_menu表字符集..." +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" -e " +SELECT + TABLE_NAME, + TABLE_COLLATION, + COLUMN_NAME, + COLUMN_TYPE, + CHARACTER_SET_NAME, + COLLATION_NAME +FROM information_schema.COLUMNS +WHERE TABLE_SCHEMA = '$DB_NAME' + AND TABLE_NAME = 'sys_menu' + AND COLUMN_NAME IN ('menu_name', 'remark'); +" 2>&1 | grep -v "Warning" + +echo "" + +# 3. 测试查询菜单数据 +echo "3. 测试查询菜单数据(检查是否有乱码)..." +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" -e " +SELECT menu_id, menu_name, remark +FROM sys_menu +WHERE parent_id = 0 +ORDER BY order_num; +" 2>&1 | grep -v "Warning" + +echo "" +echo "4. 如果上面显示有乱码,是否修复表字符集?(y/n): " +read -p "" confirm + +if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then + echo "" + echo "正在修复sys_menu表字符集..." + + # 备份表 + echo " - 创建备份表..." + mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" -e " + CREATE TABLE IF NOT EXISTS sys_menu_backup_charset AS SELECT * FROM sys_menu; + " 2>&1 | grep -v "Warning" + + # 转换表字符集 + echo " - 转换表字符集为utf8mb4..." + mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" -e " + ALTER TABLE sys_menu CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + " 2>&1 | grep -v "Warning" + + echo "" + echo "✅ 字符集修复完成!" + echo "" + echo "验证修复结果:" + mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" -e " + SELECT menu_id, menu_name, remark + FROM sys_menu + WHERE parent_id = 0 + ORDER BY order_num; + " 2>&1 | grep -v "Warning" +else + echo "" + echo "❌ 操作已取消" +fi + +echo "" +echo "============================================================" +echo "检查完成!" +echo "============================================================" diff --git a/sql/import_menu.sh b/sql/import_menu.sh index a6f5039..6dec42c 100755 --- a/sql/import_menu.sh +++ b/sql/import_menu.sh @@ -42,14 +42,14 @@ fi # 执行导入 echo "" echo "正在导入菜单数据..." -mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$SQL_FILE" +mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" < "$SQL_FILE" if [ $? -eq 0 ]; then echo "" echo "✅ 菜单数据导入成功!" echo "" echo "菜单统计:" - mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e " + mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" -e " SELECT CASE WHEN menu_id < 2000 THEN 'RuoYi系统菜单' @@ -61,7 +61,7 @@ if [ $? -eq 0 ]; then WITH ROLLUP;" echo "" echo "顶级菜单:" - mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e " + mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" --default-character-set=utf8mb4 "$DB_NAME" -e " SELECT menu_id, menu_name, order_num, visible, status FROM sys_menu WHERE parent_id = 0