MySQL 04-EMOJI 表情与 UTF8MB4 的故事

拓展阅读

MySQL View

MySQL truncate table 与 delete 清空表的区别和坑

MySQL Ruler mysql 日常开发规范

MySQL datetime timestamp 以及如何自动更新,如何实现范围查询

MySQL 06 mysql 如何实现类似 oracle 的 merge into

MySQL 05 MySQL入门教程(MySQL tutorial book)

MySQL 04- EMOJI 表情与 UTF8MB4 的故事

MySQL Expression 1 of ORDER BY clause is not in SELECT list,references column

emoji

想在 mysql 数据库插入 emoji 表情,结果报错:

### Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x8B' for column 'name' at row 1

错误原因很多小伙伴也知道,mysql 种的 utf8 和 java 的 utf-8 并不是完全对等的。

应该指定 mysql 的编码为 utf8mb4 才是正确的。

修改编码

查看编码

show variables like 'character_set_database'; # 查看数据库编码
show create table comment; # 查看表编码

修改数据库 & 表编码

可以在原来的基础上直接修改:

alter database <数据库名> character set utf8mb4; # 修改数据库
alter table <表名> character set utf8mb4; # 修改表
alter table <表名> change <字段名> <字段名> <类型> character set utf8mb4; # 修改字段

建表时指定

drop database echo_blog;
CREATE DATABASE echo_blog DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;drop table comment;
create table comment
(id int unsigned auto_increment comment '主键' primary key,create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间',update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间'
) comment '评论信息' ENGINE=Innodb default charset=UTF8MB4 auto_increment=1;

乱码问题

修改完成之后,插入成功。

但是数据库中全部是 ??? 之类的内容,而不是表情内容。

到底哪里出问题了呢?

mysql 编码问题

查看 mysql 编码

SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';

如下:

mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
+--------------------------+----------------------------------------------------+
| Variable_name            | Value                                              |
+--------------------------+----------------------------------------------------+
| character_set_client     | utf8mb4                                            |
| character_set_connection | utf8mb4                                            |
| character_set_database   | utf8mb4                                            |
| character_set_filesystem | binary                                             |
| character_set_results    | utf8mb4                                            |
| character_set_server     | utf8mb4                                            |
| character_set_system     | utf8                                               |
| character_sets_dir       | D:\tools\mysql\mysql-5.7.24-winx64\share\charsets\ |
| collation_connection     | utf8mb4_unicode_ci                                 |
| collation_database       | utf8mb4_unicode_ci                                 |
| collation_server         | utf8mb4_unicode_ci                                 |
+--------------------------+----------------------------------------------------+

属性说明:

character_set_client

主要用来设置客户端使用的字符集。通俗的讲就是mysql把客户端传递过来的数据都当成是utf8mb4

character_set_connection

主要用来设置连接数据库时的字符集,如果程序中没有指明连接数据库使用的字符集类型则按照这个字符集设置。

character_set_database

主要用来设置默认创建数据库的编码格式,如果在创建数据库时没有设置编码格式,就按照这个格式设置。

character_set_filesystem

文件系统的编码格式,把操作系统上的文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不做任何转换的。

character_set_results

数据库给客户端返回时使用的编码格式,如果没有指明,使用服务器默认的编码格式。通俗的讲就是mysql发送个客户端的数据是utf8mb4的

character_set_server

服务器安装时指定的默认编码格式,这个变量建议由系统自己管理,不要人为定义。

character_set_system

数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式。

character_sets_dir

这个变量是字符集安装的目录。

Mysql的字符集内部处理

1.mysql Server收到请求时将请求数据从 character_set_client 转换为 character_set_connection

2.进行内部操作前将请求数据从 character_set_connection 转换为内部操作字符集,步骤如下

  A. 使用每个数据字段的 CHARACTER SET 设定值;

  B. 若上述值不存在,则使用对应数据表的字符集设定值

  C. 若上述值不存在,则使用对应数据库的字符集设定值;

  D. 若上述值不存在,则使用 character_set_server 设定值。

3.最后将操作结果从内部操作字符集转换为 character_set_results

mysql charsets

临时修改配置

上面的配置都可以通过命令临时修改:

SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_database = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_server = utf8mb4;SET collation_connection = utf8mb4_unicode_ci;
SET collation_database = utf8mb4_unicode_ci;
SET collation_server = utf8mb4_unicode_ci;

当然,也可以通过修改 my.ini 配置文件。

修改 mysql 服务器配置文件

比如 windows 下个人的 mysql 安装目录为:D:\tools\mysql\mysql-5.7.24-winx64

那就在下面创建 my.ini(如果没有的话)。

内容如下:

[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4[mysqld]
# 设置3306端口
port=3306
# 允许最大连接数
max_connections=20
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODBcollation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'character-set-client-handshake = FALSE
explicit_defaults_for_timestamp=true[client]
default-character-set=utf8mb4

修改完成后需要重启 mysql 服务。

可以在 bin 下执行 mysqld restart。这个实践下来只初始化了部分编码。

个人实在 windows services(服务) 下,把 mysql 服务进行了重新启动。

jdbc 配置

druid 数据源配置

spring:datasource:druid:username: rootpassword: xxxxxxurl: jdbc:mysql://localhost:3306/echo_blog?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTCdriver-class-name: com.mysql.jdbc.Driverconnection-init-sqls: set names utf8mb4;

官方资料

https://dev.mysql.com/doc/connectors/en/connector-j-reference-charsets.html

Notes
For Connector/J 8.0.12 and earlier: In order to use the utf8mb4 character set for the connection, the server MUST be configured with character_set_server=utf8mb4; if that is not the case, when UTF-8 is used for characterEncoding in the connection string, it will map to the MySQL character set name utf8, which is an alias for utf8mb3.For Connector/J 8.0.13 and later:When UTF-8 is used for characterEncoding in the connection string, it maps to the MySQL character set name utf8mb4.If the connection option connectionCollation is also set alongside characterEncoding and is incompatible with it, characterEncoding will be overridden with the encoding corresponding to connectionCollation.Because there is no Java-style character set name for utfmb3 that you can use with the connection option charaterEncoding, the only way to use utf8mb3 as your connection character set is to use a utf8mb3 collation (for example, utf8_general_ci) for the connection option connectionCollation, which forces a utf8mb3 character set to be used, as explained in the last bullet.Warning
Do not issue the query SET NAMES with Connector/J, as the driver will not detect that the character set has been changed by the query, and will continue to use the character set configured when the connection was first set up.

说明:

提示
mysql-connector-java 版本在8.0.12之前的,包括8.0.12,服务端必须设置character_set_server=utf8mb4;如果不是的话,就算设置了characterEncoding=UTF-8,照样会被设置为MYSQL的 utf8字符集,也就是utf8mb3。对于8.0.13和以后的版本,如果设置了characterEncoding=UTF-8,他会映射到MYSQL的utf8mb4字符集。如果connectionCollation 也和characterEncoding一起设置了,但是不兼容,characterEncoding会被connectionCollation的设置覆盖掉。由于没有Java-Style的utfmb3对应的字符集名称可以用在connection选项charaterEncoding上,唯一的设置utf8mb3的方式就是在连接选项设置utf8mb3 collation(例如utf8_general_ci),这会强制使用utf8mb3字符集,正如上文所述。警告
不要通过Connector发起SET NAMES指令,因为driver不会检测字符集是不是被查询语句改动,并且当连接第一次建立之后,会继续使用当时的字符集设置。

可以发现 jdbc 中的配置 connection-init-sqls: set names utf8mb4; 这句话是没啥用的。

建议老老实实的修改 mysql 服务端的配置。

依然乱码

这个时候 java 客户端保存 emoji,依然有部分乱码。

比如:

💔✊💓💖😧😯 I Love this!

用命令行查看,数据库变成了:

 �✊���� I Love this!

部分乱码? what's up?

java 程序断点

在 java 应用中进行断点,发现内容是对的。

mysql 命令行插入

我们直接在 mysql 命令行执行插入:

insert into comment (content) values ('💔✊💓💖😧😯 I Love this!');

MD,发现无法执行,这条路走不通。

命令行终端不支持 emoji 表情。

乱码的原因

这个乱码是因为 mysql 终端导致的,还是别的原因?

我们测试一下,使用 java 程序对内容进行查询。

测试代码

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class CommentServiceTest {@Autowiredprivate CommentService commentService;@Testpublic void selectTest() {Comment comment = commentService.selectById(20);System.out.println(comment);}}

测试效果

日志如下:

Comment{id=20, content=💔✊💓💖😧😯 I Love this!, ackFlag=N, createTime=Sun Aug 15 10:13:56 CST 2021, updateTime=Sun Aug 15 10:13:56 CST 2021}

可以发现,存储的数据本身是没有问题的。

是命令行终端的问题。

命令行的问题

已有的命令行

一开始使用的是 windows10 自带的 cmd,发现不行。

使用 cmder 命令行,还是不行。

powershell

我们测试下微软商店的 Terminal 命令行,也就是新版本的 powershell。

cd D:\tools\mysql\mysql-5.7.24-winx64\bin
.\mysql -uroot -p

登录后执行查询,结果如下:

💔✊💓💖😧😯 I Love this! 

纠结了半天的乱码,经确认是命令行终端的问题。

参考资料

MySQL的utf8、utf8mb4、编码问题详解

mysql字符集utf8mb4失效踩坑

Mysql UTF-8mb4字符集的问题

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

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

相关文章

产品思维训练 | 熊孩子任性打赏从产品角度有哪些方法可以规避?

本周话题&#xff1a; 抖音回应10岁儿童打赏主播10万&#xff1a;已全额退款。正值特殊时期&#xff0c;小朋友们花费在直播APP中的时间也不少。 对于打赏等行为&#xff0c;当然需要家长加强监督&#xff0c;除此之外&#xff0c;产品方面可以做什么措施&#xff0c;压制住胡…

【JS】获取接口返回 EventStream 结构的数据(即接收读取 stream 流)

文章目录 EventStream 是一种服务器推送的数据格式&#xff0c;可以用于实时数据传输。 接口返回的示例图 获取示例&#xff1a; // 这里的 url 为虚拟的&#xff0c;仅供演示用 fetch(https://test.cn.com/api/agent/2, {method: POST,headers: {Content-Type: applicatio…

提取图片地理位置

引言 在数字化时代&#xff0c;图片已经成为我们生活中不可或缺的一部分。然而&#xff0c;如何从图片中提取有用的信息&#xff0c;尤其是地址信息&#xff0c;一直是一个具有挑战性的问题。Python作为一种强大的编程语言&#xff0c;为我们提供了丰富的工具和库来解决这个问…

【SGDR】《SGDR:Stochastic Gradient Descent with Warm Restarts》

arXiv-2016 code: https://github.com/loshchil/SGDR/blob/master/SGDR_WRNs.py 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method5 Experiments5.1 Datasets and Metric5.2 Single-Model Results5.3 Ensemble Results5.4 Experiment…

智慧污水井物联网远程监控案例

智慧污水井物联网远程监控案例 在当今数字化转型的浪潮中&#xff0c;智慧水务已成为城市基础设施建设的重要组成部分。其中&#xff0c;基于物联网技术的智慧污水井远程监控系统以其高效、精准、实时的特性&#xff0c;在提升污水处理效能、保障城市水环境安全、实现精细化管…

每日一题 — 水果成篮

思路&#xff1a; 通过阅读上面文字得出问题&#xff1a;就去只有两个种类的最大长度的连续子数组&#xff0c;这时我们可以想到用哈希表来存储数据&#xff0c;记录数据的种类和每个种类的数量。 解法一&#xff1a;暴力递归&#xff08;right每次遍历完都回退&#xff09; 解…

oceanbase一键安装

安装文档&#xff1a;https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000642554 软件下载 https://www.oceanbase.com/softwarecenter 安装obd yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/oceanbase/OceanBa…

无线游戏手柄的测试(Windows11系统手柄调试方法)

实物 1、把游戏手柄的无线接收器插入到电脑usb接口中 2、【控制面板】----【查看设备和打印机】 3、【蓝牙和其它设备】--【更多设备和打印机设置】 4、鼠标右键【游戏控制器设置】 5、【属性】 6、【测试】&#xff08;每个按键是否正常&#xff09; 7、【校准】&#xff08;…

稀碎从零算法笔记Day46-LeetCode:互质树

这几天有点懈怠了 题型&#xff1a;树、DFS、BSF、数学 链接&#xff1a;1766. 互质树 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个 n 个节点的树&#xff08;也就是一个无环连通无向图&#xff09;&#xff0c;节点编号从 0 到 …

从“黑箱”到“透明”:云里物里电子标签助力汽车总装数字化转型

“汽车总装”指“汽车产品&#xff08;包括整车及总成等&#xff09;的装配”&#xff0c;是把经检验合格的数以百计、或数以千计的各种零部件按照一定的技术要求组装成整车及发动机、变速器等总成的工艺过程&#xff0c;是汽车产品制造过程中最重要的工艺环节之一。 其中&…

算法 囚犯幸存者

题目 主类 public static List<Prisoner> prisoners new ArrayList<Prisoner>(); public static List<Prisoner> remainPrisoners new ArrayList<Prisoner>(); public static Prisoner lastPrisoner null;public static void main(String[] args) …

一款自研Python解释器

项目简介: PikaScript是一个完全重写的超轻量级python引擎,具有完整的解释器,字节码和虚拟机架构,可以在少于4KB的RAM下运行,用于小资源嵌入式系统。相比同类产品,如MicroPython,LuaOS等,资源占用减少85%以上。 入选2021年度 Gitee最有价值开源项目,加入RT-Thread嵌入…

vue3+ts中判断输入的值是不是经纬度格式

vue3ts中判断输入的值是不是经纬度格式 vue代码&#xff1a; <template #bdjhwz"{ record }"><a-row :gutter"8" v-show"!record.editable"><a-col :span"12"><a-input placeholder"经度" v-model:v…

linux使用docker实现redis主从复制和哨兵模式

目录 1. 拉取redis镜像 2.使用可视化redis工具 3. 设置从redis 4.设置哨兵模式 5. 使用docker-compose快速创建 1. 拉取redis镜像 docker pull redis 默认拉取最新的镜像。 然后pull结束后使用docker images检查镜像&#xff1a; 然后docker run创建container容器 首先…

速率再次翻倍!现有SSD显卡又要被强制换代了

去年 AMD Ryzen 7000 和 Intel 第 13 代 CPU 发布的同时&#xff0c;消费级的 PCI-E 5.0 平台出现在了大众视野。 这个用了快 20 年的接口虽然外形上似乎没变过、新老平台通吃&#xff0c;但其实内在已更新了好多个版本了。 和 3.0 换 4.0 一样&#xff0c;5.0、6.0 换代只是时…

【自研网关系列】网关的技术选型以及架构设计

&#x1f308;Yu-Gateway&#xff1a;基于 Netty 与原生 Java 实现&#xff0c;使用 Nacos 作为注册与配置中心。项目实现多种过滤器&#xff0c;包含路由、负载均衡、鉴权、灰度发布等过滤器。 &#x1f308;项目代码地址&#xff1a;GitHub - YYYUUU42/YuGateway-master 如果…

【Linux】进程间通信——system V版本 共享内存

目录 共享内存 原理 实践 shmget() 创建共享内存 shmctl() 删除共享内存 shmat() 挂接进程和共享内存 shmt() 进程和共享内存去关联 共享内存的特性 优势 劣势 用共享内存实现进程间通信 共享内存 原理 两个进程的PCB各自维护着一个进程地址空间。当两个进…

Linux的学习之路:8、Linux调试器-gdb使用

摘要 本章主要是说一下gdb的使用&#xff0c;以及把使用指令放入放个指令手册。 目录 摘要 一、背景 二、使用 1、产生debug文件 2、进入gdb 3、使用指令 三、思维导图 一、背景 Linux调试器gdb的背景主要涉及到Linux程序发布方式和调试需求。 在Linux中&#xff0c…

SpringBoot学习笔记二

SpringBoot学习笔记二 1.SpringBoot配置加载顺序1.1 内部配置加载顺序1.2 外部配置加载顺序 2. SpringBoot整合其他框架2.1 SpringBoot整合Test2.2 SpringBoot整合Redis 1.SpringBoot配置加载顺序 1.1 内部配置加载顺序 同理可知&#xff0c;父项目中的confg下的配置优先级最…

探索Java中的栈:Stack与Deque(ArrayDeque和LinkedList)

文章目录 1. 栈&#xff08;Stack&#xff09;1.1 定义方式1.2 特点1.3 栈的层次结构 2. 双端队列&#xff08;Deque&#xff09;2.1 定义方式及继承关系2.2 特点&#xff1a;2.3 ArrayDeque2.4 LinkedList2.5 Deque 的各种方法2.6 如何选择ArrayDeque和LinkedList 3. 如何选择…