设为首页 收藏本站
查看: 865|回复: 0

[经验分享] Mysql中文乱码解决思路和过程

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-1-2 09:22:59 | 显示全部楼层 |阅读模式
本帖最后由 fiollr 于 2014-1-2 09:28 编辑

  Mysql 中文乱码问题是常见的问题,解决也是不难的,本文将通过我在遇到问题时候,如何的查找和解决为导向,来呈现分析解决问题的思路和过程。
    在JavaEE项目开发中,通常的中文乱码问题分为web前端,web后端,数据库乱码,,一但排除了web端的中文乱码,也就说乱码问题是在数据库端发生的了。
问题产生:    首先在创建用户,如图1所示:
Center.jpg

              图1
    在点击增加用户的时候,数据库中userName字段显示为乱码:

  • mysql> select * from t_user;
    +--------+----------+------+---------------------+-------+
    | userId | userName | age  | birthday            | isVip |
    +--------+----------+------+---------------------+-------+
    |      1 | ????     |    0 | 2014-01-01 00:00:00 |     1 |
    +--------+----------+------+---------------------+-------+
    1 row in set (0.00 sec)


解决思路    在javaweb项目中,在解决乱码问题之前,首先要确保是在数据库这里发生乱码,如果确实在数据库这端发生乱码,请试着通过以下步骤查找原因:


步骤一:查看数据库编码状态,如下所示:
  • mysql> status;
    --------------
    mysql  Ver 14.12 Distrib 5.0.22, for Win32 (ia32)

    Connection id:          3
    Current database:       steven
    Current user:           root@localhost
    SSL:                    Not in use
    Using delimiter:        ;
    Server version:         5.0.22-community-nt
    Protocol version:       10
    Connection:             localhost via TCP/IP
    Server characterset:    latin1
    Db     characterset:    latin1
    Client characterset:    latin1
    Conn.  characterset:    latin1
    TCP port:               3306
    Uptime:                 2 hours 10 min 15 sec

    Threads: 1  Questions: 121  Slow queries: 0  Opens: 2  Flush tables: 1  Open tab
    les: 0  Queries per second avg: 0.015
    --------------


      发现Server,Db,Client,Conn.的字符编码均为latin1,所以一定会出现中文乱码的情况。
解决方案一:(window下)
通过MySQL Server Instance Configuration Wizard重新设置编码方案,如图2所示:
Center.jpg

                      图2
然后一直Next,然后到Please select the database usage 的时候选择第三项,如图3所示:
Center.jpg

                      图3
接着一直Next,到Please select the default character set.的时候选择gbk,字符编码,如图4所示:
Center.jpg

                  图4
这个时候一直Next,确认密码后,Next,然后就Execute执行,如图5所示:
Center.jpg

                    图5
Finish后,退出数据库命令控制台然后再进去,查看数据库编码状态,如下所示:
mysql> use steven;
Database changed
mysql> status;
--------------
mysql  Ver 14.12 Distrib 5.0.22, for Win32 (ia32)

Connection id:          2
Current database:       steven
Current user:           root@localhost
SSL:                    Not in use
Using delimiter:        ;
Server version:         5.0.22-community-nt
Protocol version:       10
Connection:             localhost via TCP/IP
Server characterset:    gbk
Db     characterset:    latin1
Client characterset:    gbk
Conn.  characterset:    gbk
TCP port:               3306
Uptime:                 1 min 20 sec

Threads: 1  Questions: 12  Slow queries: 0  Opens: 0  Flush tables: 1  Open tabl
es: 6  Queries per second avg: 0.150
--------------

发现编码除了Db characterset外其他的都改为gbk了,这是方案一,依然可以实现这样的更改。


解决方案二:通过配置文件,找到Mysql安装的目录,找到根目录下my.ini文件,如图6所示:
   20131231142057000.png    图6
然后打开后,进行如下更改,如图7所示:
Center.jpg

                       图7
将latin1更改gbk编码方式,
然后将数据库服务重新启动,如下所示:
C:\Users\Administrator>net stop mysql
The MySQL service is stopping.
The MySQL service was stopped successfully.


C:\Users\Administrator>net start mysql
The MySQL service is starting.
The MySQL service was started successfully.

这个时候和方案一一样的效果,然而此时并没有解决问题。
  • mysql> use steven;
    Database changed
    mysql> status;
    --------------
    mysql  Ver 14.12 Distrib 5.0.22, for Win32 (ia32)

    Connection id:          2
    Current database:       steven
    Current user:           root@localhost
    SSL:                    Not in use
    Using delimiter:        ;
    Server version:         5.0.22-community-nt
    Protocol version:       10
    Connection:             localhost via TCP/IP
    Server characterset:    gbk
    Db     characterset:    latin1
    Client characterset:    gbk
    Conn.  characterset:    gbk
    TCP port:               3306
    Uptime:                 1 min 20 sec

    Threads: 1  Questions: 12  Slow queries: 0  Opens: 0  Flush tables: 1  Open tabl
    es: 6  Queries per second avg: 0.150
    --------------



步骤二:改变Db characterset的编码方式,执行以下sql语句:
--修改数据库编码为gbk
alter database steven character set gbk;
其中steven是数据表乱码所在的数据库,这个时候执行status查看
mysql> status;
--------------
mysql  Ver 14.12 Distrib 5.0.22, for Win32 (ia32)

Connection id:          2
Current database:       steven
Current user:           root@localhost
SSL:                    Not in use
Using delimiter:        ;
Server version:         5.0.22-community-nt
Protocol version:       10
Connection:             localhost via TCP/IP
Server characterset:    gbk
Db     characterset:    gbk
Client characterset:    gbk
Conn.  characterset:    gbk
TCP port:               3306
Uptime:                 8 min 30 sec

Threads: 1  Questions: 32  Slow queries: 0  Opens: 1  Flush tables: 1  Open tabl
es: 7  Queries per second avg: 0.063
--------------

此时都成为gbk的编码格式了。
    注:如果此时数据库编码默认就为gbk的编码方式的,此时问题一般都已经解决了,如果还没有解决,在插入含有中文数据的时候会有以下异常:
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'userName' at row 1
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3489)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2019)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1937)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1922)
        at com.steven.util.DaoHandle.executeDML(DaoHandle.java:49)
        at com.steven.dao.impl.UserDao.doCreate(UserDao.java:33)
        at com.steven.model.UserAddAction.execute(UserAddAction.java:80)
        at com.steven.controller.ActionServlet.doPost(ActionServlet.java:40)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at com.steven.util.EncodeFilter.doFilter(EncodeFilter.java:35)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:722)


说数据过长,此时查看数据表默认编码方式如下所示:
mysql> show create table t_user;
+--------+----------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------------+
| Table  | Create Table


                                        |
+--------+----------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------------+
| t_user | CREATE TABLE `t_user` (
  `userId` int(10) NOT NULL auto_increment,
  `userName` varchar(100) NOT NULL,
  `age` int(2) default NULL,
  `birthday` datetime default NULL,
  `isVip` tinyint(1) default NULL,
  PRIMARY KEY  (`userId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+--------+----------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------------------+
1 row in set (0.00 sec)
会发现数据表默认编码是latin1,所以异常的原因就是中文的编码和表的默认编码不匹配,造成数据冲突引起的。


步骤三:解决异常
执行以下两句进行更改数据库的默认编码方式;
方案一:drop表,然后重新建表,建表语句如下所示;
  • create table t_user(
            userId            int(10)         not null primary key auto_increment,
            userName    varchar(100) not null,
            age                int(2),
            birthday    datetime,
            isVip       boolean
    ) DEFAULT CHARSET=utf8;

方案二:mysql自带的命令
执行以下两句命令:
--修改表默认用gbk
alter table t_user character set gbk;
--修改userName字段编码为gbk
alter table t_user modify userName varchar(100) CHARACTER SET gbk;

执行完之后,数据库字段和表的编码方式都更改为了gbk,此时在进行插入数据时候,数据表中的数据为:
mysql> select * from t_user;
+--------+----------+------+---------------------+-------+
| userId | userName | age  | birthday            | isVip |
+--------+----------+------+---------------------+-------+
|      1 | ????     |    0 | 2014-01-01 00:00:00 |     1 |
|      2 | 元旦快乐 |    0 | 2014-01-01 00:00:00 |     1 |
+--------+----------+------+---------------------+-------+
2 rows in set (0.00 sec)
第一条为乱码时候插入的数据,第二条为解决后插入的数据,此时Mysql数据库编码已经解决了。


总结:
对于数据库乱码解决方案,可以归纳如下:
  • 通过软件或者配置文件进行第一步修改编码
  • 通过mysql命令更改数据库编码(如果默认编码支持中文,此步骤就可以省略了)
  • 发生Data too long for column……异常,进行数据表字符编码更改

    一般情况的mysql数据库中文编码问题即可得到解决,编码同样可以设置成utf8编码方式,但有时会出现数据库中编码是繁体字的现象,然后执行set names "gbk"命令,即可成功显示简体中文。
    下面提供常用的修改中文字符乱码的mysql命令:
set names 'gbk';
--它相当于下面的三句指令:
set character_set_client = gbk;
set character_set_results = gbk;
set character_set_connection = gbk;

--显示数据表表的编码
show create table t_user(表的名称);

--修改数据库编码为gbk
alter database steven(数据库的名称) character set gbk;

--修改表默认用gbk
alter table t_user(表的名称) character set gbk;

--修改userName字段编码为utf8
alter table t_user(表的名称) modify userName(表中字段的名称) varchar(100) CHARACTER SET gbk;

--创建表
create table t_user(
        userId            int(10)         not null primary key auto_increment,
        userName    varchar(100) not null,
        age                int(2),
        birthday    datetime,
        isVip       boolean
) DEFAULT CHARSET=utf8;
祝大家学习愉快,元旦快乐!




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-12987-1-1.html 上篇帖子: Mysql Replication(主从服务器)配置实例 下篇帖子: 虚拟机centos6.3 安装 mysql5.6.15 并设置 mysql主从复制 中文
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表