字符集参考文献:

http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_character_set_connection

http://dev.mysql.com/doc/refman/5.6/en/faqs-cjk.html

今天,一开发同事使用jdbc连接数据库执行一条语句无结果集,但是通过sqlyou执行相同的语句有返回结果。

执行的语句where条件中含有中文,这应该是字符集引起的

此开发测试实例刚迁移不久的,查看迁移前的环境默认字符集都是utf8

查看当前数据库的字符集

mysql> show variables like '%charac%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.00 sec)
  • character_set_client
  • character_set_connection
  • character_set_results

   以上三个控制mysql client的字符集

  • character_set_database

设置数据库的默认字符集

  • character_set_server

设置以上所有的默认字符集

发现server端的字符集和client端的全局字符集设置变量都是采用的默认值latin1

发现配置文件中没有添加参数项  character-set-server=utf8

造成乱码的原因:

数据存储时的编码解码过程

jdbc=>character_set_client=>table character

每个环节的字符集编码都是utf8,没有转码过程

character_set_client变为latin1后,读取数据的解码过程为

jdbc<=character_set_client<=table character

表中存储的是utf8编码格式,判断和character_set_client不一致则转码为latin1的二进制流,然后传输给远端的客户端,

客户端jdbc通过设置的字符集展示结果,使用utf8展示latin1,所以出现了乱码。

解决办法

# character_set_filesystem 、character_set_system 、character_sets_dir除外都变更全局为utf8

所有的应用需要重连数据库才能变更会话级别的字符集

对于在字符集设置为latin1期间插入的数据编码存储过程:

  • 在terminal(这里为jdbc客户端)中使用输入法输入
  • terminal转换成utf8二进制流
  • 二进制流通过MySQL客户端传输到MySQL Server
  • Server通过character-set-client解码
  • 判断character-set-client和目标表的charset是否一致,character-set-client为latin1,目标表的字符集为utf8
  • 不一致则进行一次从client-charset到table-charset的一次字符编码转换,由latin1转码为utf8
  • 将转换后的字符编码二进制流存入文件中

测试这种情况下将 中间环节的character-set-client变更为utf8,是否会出现乱码

mysql> show  variables like '%char%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.01 sec) mysql> update t1 set col='建军节' where id=4; mysql> select * from t1 where id=4;
+----+-----------+------+
| id | col | time |
+----+-----------+------+
| 4 | 建军节 | NULL |
+----+-----------+------+ 解码编码转储 crt terminal =》character_set_client =》character_set_server
utf8 latin1 utf8
如果查询时任何一个环节的字符集变化都可能会造成乱码
更改不同环节的字符集对应的数据显示
1、改变客户端的字符集
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec) mysql> select * from t1 where id=4;
+----+-----------------------+------+
| id | col | time |
+----+-----------------------+------+
| 4 | ??o???è?? | NULL |
+----+-----------------------+------+
2、更改crt terminal 的字符集为default
mysql> select * from t1 where id=4;
+----+-----------+------+
| id | col | time |
+----+-----------+------+
| 4 | 寤哄啗鑺 | NULL |
+----+-----------+------+
3、更改表字段字符集
ALTER TABLE t1 CHANGE col col varchar(10) CHARACTER SET latin1; mysql> select * from t1 where id=4;
+----+-----------+------+
| id | col | time |
+----+-----------+------+
| 4 | 建军节 | NULL |
+----+-----------+------+

更改表的字符集为latin1,读取数据涉及到变更的环节变为

  • 从文件读出二进制数据流(utf8存入)
  • 用表字符集latin1编码进行解码
  • 将数据转换为character-set-client的编码laint1

对应的变更前的环节:

  • 从文件读出二进制数据流(utf8存入)
  • 用表字符集utf8编码进行解码
  • 将数据转换为character-set-client的编码laint1

可以看出更改表数据字符集没有导致乱码的原因是,字符集整体经历的解码和转码过程是一致的,都经历了一次由utf8到latin1的转码。

另一有关字符集的问题:为了支持表情符号,将系统级别的utf8设置为utf8mb4且相应的表也做了字符集的转变,重启应用不生效,重启数据库和应用才会生效

参考文章为:

http://blog.sina.com.cn/s/blog_93b45b0f0101glfx.html

参考文章:

  编码解码过程  : http://cenalulu.github.io/mysql/mysql-mojibake/

MySQL 配置文件中忘配置default-character-set引发的乱码问题的更多相关文章

  1. 【转】MyBatis学习总结(三)——优化MyBatis配置文件中的配置

    [转]MyBatis学习总结(三)——优化MyBatis配置文件中的配置 一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置信息写在了MyBatis的con ...

  2. Mybatis系列(二):优化MyBatis配置文件中的配置和解决字段名与实体类属性名不相同的冲突

    原文链接:http://www.cnblogs.com/xdp-gacl/p/4264301.html     http://www.cnblogs.com/xdp-gacl/p/4264425.ht ...

  3. Prometheus 配置文件中 metric_relabel_configs 配置--转载

    Prometheus 配置文件中 metric_relabel_configs 配置 参考1:https://www.baidu.com/link?url=YfpBgnD1RoEthqXOL3Lgny ...

  4. MyBatis学习总结(三)——优化MyBatis配置文件中的配置(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013548.html 一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置 ...

  5. MyBatis入门学习教程-优化MyBatis配置文件中的配置

    一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置信息写在了MyBatis的conf.xml文件中,如下: 1 <?xml version=" ...

  6. MyBatis学习总结(三)——优化MyBatis配置文件中的配置

    一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置信息写在了MyBatis的conf.xml文件中,如下: 1 <?xml version=" ...

  7. MyBatis学习总结(三)——优化MyBatis配置文件中的配置

    一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置信息写在了MyBatis的conf.xml文件中,如下: <?xml version="1 ...

  8. MyBatis——优化MyBatis配置文件中的配置

    原文:http://www.cnblogs.com/xdp-gacl/p/4264301.html 一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置信息写 ...

  9. MyBatis学习总结_03_优化MyBatis配置文件中的配置

    一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置信息写在了MyBatis的conf.xml文件中,如下: 1 <?xml version=" ...

随机推荐

  1. Android 升级SQLite数据库

    每一个数据库版本都会对应一个版本号,当指定的数据库版本号大于当前数据库的版本号时,就会进入到onUpGrade()方法中去执行更新操作.需要为每一个版本号赋予其各自改变的内容然后再onUpgrade( ...

  2. 搭建ubuntu14.04的hadoop集群【docker容器充当服务器】

    首先弄出来装有hadoop.java.ssh.vim的镜像起名badboyf/hadoop.做镜像有两种方法,一种是用Dockerfile来生成一个镜像,一种是基于ubuntu14.04的基础镜像生成 ...

  3. Docker实践,来自沪江、滴滴、蘑菇街架构师的交流分享

    架构师小组交流会:每期选一个时下最热门的技术话题进行实践经验分享. 第一期主题:容器实践.Docker 作为当前最具颠覆性的开源技术之一,其轻量虚拟化.可移植性是CI/CD,DevOps,微服务的重要 ...

  4. plist基本操作

    重要概念:某些路径下“只能读,不能写”的原因 iPhone.ipad真机上 Resouces文件夹:是只读的,无法写入. document 和temp文件夹:可读,可写. 一.工程结构

  5. Snoopy+phpquery采集demo

    用phpquery类,写了个采集的demo,以 某网贷平台的 一个列表为例,我们要采集该平台下面的 各平台名称,结构树如下 include 'phpQuery.php'; phpQuery::newD ...

  6. svg转化成canvas以便生成base64位的图片

    很久前写了关于把html转成图片的一个例子,最近有出了新的问题.利用html2canvas.js文件把html转成base64位的图片是没什么问题的,但也不是绝对的,比如这时候不能碰见svg这个鬼,h ...

  7. Java主函数定义

    public static void main(String[] args){} public: main主方法是由jvm来调用的,jvm实际也是一个程序,为了保证jvm能够在任何情况下来调用主函数. ...

  8. Lamp(Ubuntu 12.04 LTS) 之 htaccess的使用

    环境说明:Ubuntu 12.04 LTS Lamp (以apt方式分别安装) 一.明确目标:要确保.htaccess文件起作用,只需要三个重要点: 1.开启apache rewrite模块: (1) ...

  9. 深入springMVC源码------文件上传源码解析(下篇)

    在上篇<深入springMVC------文件上传源码解析(上篇) >中,介绍了springmvc文件上传相关.那么本篇呢,将进一步介绍springmvc 上传文件的效率问题. 相信大部分 ...

  10. applicationContext配置文件中的属性说明

    lazy-init:设置只对scop属性为singleton的bean起作用. 1.true:延迟加载:这时在第一次向容器通过getBean索取bean时实例化的. 2.false:表示spring启 ...