gorm记一次“mysql写入 Error 1366 (HY000): Incorrect string value”错误

news/2024/11/29 22:48:41/

记一次“mysql写入 Error 1366 (HY000): Incorrect string value”错误

环境go+gorm+docker+mysql

写入数据库的内容为中文时提示Error 1366 (HY000): Incorrect string value: '\xE6\x9D\x8E\xE7\x99\xBD' for column 'nickName' at row 1,原因是创建表时没有指定字符集为utf8
解决方案: 创建数据库表时指定表为utf8,gorm的设置是在AutoMigrate函数调用前指定表的字符集:

db.Set("gorm:table_options", "CHARSET=utf8").AutoMigrate(&entity.UserInfo{})
db.Create(&record)

检查是否生效,进入docker中mysql Terminal,输入show create table TbUserInfo;查看建表语句,如下:

mysql> show create table TbUserInfo;
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                                                                                                                                                                                              |
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TbUserInfo | CREATE TABLE `TbUserInfo` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,`accountName` varchar(191) DEFAULT NULL,`nickName` varchar(191) DEFAULT NULL,`portraitURL` longtext,`birthday` longtext,`phone` longtext,`gender` longtext,PRIMARY KEY (`id`),UNIQUE KEY `accountName` (`accountName`),UNIQUE KEY `nickName` (`nickName`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 |
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

说明go代码指定建表的字符为utf8确实生效了。如果建表时没有指定utf8,建表信息就是如下所示:

```log
mysql> show create table TbUserInfo;
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                                                                                                                                                                               |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TbUserInfo | CREATE TABLE `TbUserInfo` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,`accountName` varchar(191) DEFAULT NULL,`nickName` varchar(191) DEFAULT NULL,`portraitURL` longtext,`birthday` longtext,`phone` longtext,`gender` longtext,PRIMARY KEY (`id`),UNIQUE KEY `accountName` (`accountName`),UNIQUE KEY `nickName` (`nickName`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

经过上述go代码修改,写入数据库成功,通过我的查询代码,查出来我的插入数据为

{"code": 2013,"info": "{\"ID\":1,\"AccountName\":\"leebai\",\"NickName\":\"李白\",\"PortraitURL\":\"localhost:8080/path\",\"Birthday\":\"1990-01-01\",\"Phone\":\"13688449696\",\"Gender\":\"male\"}"
}

说明确实成功了。

对于业务流程来说确实已经解决了,没有问题了,此时我想要到我的dockermysql容器中去看看我的插入数据是什么样的,查询结果如下:

sh-4.2# mysql -u root -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.41 MySQL Community Server (GPL)Copyright (c) 2000, 2023, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> use mall;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> show tables;
+----------------+
| Tables_in_mall |
+----------------+
| TbUserInfo     |
+----------------+
1 row in set (0.00 sec)mysql> select * from TbUserInfo;
+----+-------------+----------+---------------------+------------+-------------+--------+
| id | accountName | nickName | portraitURL         | birthday   | phone       | gender |
+----+-------------+----------+---------------------+------------+-------------+--------+
|  1 | leebai      | ??       | localhost:8080/path | 1990-01-01 | 13688449696 | male   |
+----+-------------+----------+---------------------+------------+-------------+--------+
1 row in set (0.00 sec)

可以看到nickName所在列的中文变成了??,但是我们的go程序是可以返回正常的中文李白的,所以怀疑是mysql容器中的客户端连接工具的字符集有问题,
输入如下命令,查询客户端的字符集是latin1,该字符集无法显示中文字符。

mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)mysql> show variables like 'collation%';
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| collation_connection | latin1_swedish_ci  |
| collation_database   | latin1_swedish_ci  |
| collation_server     | utf8mb4_unicode_ci |
+----------------------+--------------------+
3 rows in set (0.00 sec)

经过一番面向Google查询,只需要修改mysql容器/etc目录下的my.cnf文件即可。具体修改步骤为在[client]项下加入default-character-set=utf8即可。修改后整个文件如下所示:

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock
default-character-set=utf8!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

修改之后,重启mysql容器,重新登录mysql,执行select * from TbUserInfo;,查询结果如下:

mysql> select * from TbUserInfo;
+----+-------------+----------+---------------------+------------+-------------+--------+
| id | accountName | nickName | portraitURL         | birthday   | phone       | gender |
+----+-------------+----------+---------------------+------------+-------------+--------+
|  1 | leebai      | 李白     | localhost:8080/path | 1990-01-01 | 13688449696 | male   |
+----+-------------+----------+---------------------+------------+-------------+--------+
1 row in set (0.00 sec)

可以看到: ??变成了李白,说明配置修改生效。

注意: 运行docker-compose up -d重新部署mysql容器会导致my.cnf中的配置项丢失。T_T


http://www.ppmy.cn/news/61998.html

相关文章

word@论文后期优化和完善工作@页眉页脚页码@配置并导出pdf

文章目录 论文结构例 目录操作页眉页脚页眉样式检查所有页面的页眉添加横线 页码从第二页(封面后的一页)开始用罗马数字标页码 word导出pdf等其他格式额外配置带独立书签和目录打印pdf 最后的优化 论文结构 一篇规范的论文应该大致包括以下部分: 标题页&#xff1…

SeaweedFS学习笔记:Filer服务,目录与文件

文章目录 1. 介绍2. 用法2.1 生成配置文件2.2 启动 filer 3. 读写流程3.1 读取流程3.2 写入流程 4. Filer Store4.1 复杂度4.2 Filer的使用场景 5. 数据加密5.1 对Volume server的数据进行加密 1. 介绍 文件系统,一般都离不开目录和文件,当我们把Seawee…

MATLAB算法实战应用案例精讲-【人工智能】对比学习(概念篇)(补充篇)

目录 前言 几个高频面试题目 基于对比学习(ContrastiveLearning)的文本表示模型【为什么】能学到文本【相似】度? 为什么对比学习能学到很好的语义相似度? 那么如何评价这个表示空间的质量呢? 知识储备 监督学习和非监督学习 算法原理…

04-菜单维护 尚筹网

在【菜单维护】页面,通过树形结构,使用zTree显示整个菜单。 准备工作 一、在数据库创建菜单表: #使用project_rowd表 use project_rowd;#创建菜单的数据库表 create table t_menu (id int(11) not null auto_increment, pid int(11), nam…

IDEA沉浸式编程体验

前言 IntelliJ IDEA:前不久推出了一个新的概念Fleet编辑器。用过的人都知道,不过是模仿VScode整一套,但相比之下,fleet虽然在传统IDEA的基础上简约了不少,一旦打开智能模式,那内存占用刷一下就上去了,没个3…

【python学习】基础篇-文件与系统-写入内容到指定文件

利用文件对象提供的 write() 方法,可以向文件中写入内容。 语法格式如下: file.write(string) 其中,fle 为打开的文件对象: string 为要写入的字符串。 fopen(word.txt, a) # 以追加的方式打开文件 # 将信息写入文件 f.write("有时候你觉得特别难&…

TikTok数据报告要怎么看?

TikTok数据报告是一种分析和汇总TikTok平台上数据的报告,包含TikTok平台上的用户数据、视频数据、广告数据等。TK卖家每年可以通过分析TK数据报告来更好地了解受众和市场趋势,从而制定更加精准的营销策略和提升销售业绩。TikTok数据报告也可以帮助商家更…

很佩服的一个Google大佬,离职了。。

这两天,科技圈又有一个突发的爆款新闻相信不少同学都已经看到了。 那就是75岁的计算机科学家Geoffrey Hinton从谷歌离职了,从而引起了科技界的广泛关注和讨论。 而Hinton自己也证实了这一消息。 提到Geoffrey Hinton这个名字,对于一些了解过…