日期:2014-05-16  浏览次数:20414 次

关于解决mysql和jsp乱码问题的总结

问题的本质是:应用程序采用的字符集与数据库(mysql)采取的编码集不一致。产生问题的关键原因是,我们都是在基本功能做完后才去解决乱码问题,因此,按照网上大多数人介绍的方法,去修改数据库配置文件my.ini,通过指令直接去修改数据库或者表的字符集,都没有生效。后来,尝试在上述方法后新建一个表,发现问题解决,又查到,可以通过mysql> ALTER table tablename modify 字段名 varchar(100) CHARACTER SET gb2312;来强制指定现有表格的某些字段的字符编码集,总算解决了所有问题。

?

前两天项目中遇到mysql乱码的问题,折腾了好几天,查了好多资料,最后在恍然大悟中解决了。今天先简单的说说这个事,然后把在这个事中查找学习到的心得记录下来,以与大家分享,亦备后用。


一.我把所有页面,所有请求都编码都统一用utf-8,使用Filter过滤所有request和response都设成utf-8,数据库character_set_database设置utf-8,我知道character_set_client还是默认的latin1但是我在连接数据库时url后面转码了:
?? ?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true。
结果问题依旧!哪怕我在代码中用jdbc直接insert into 表 values(中文),在数据库中client用select查询都是乱码,用jdbc查出来打印到日志上是乱码,显示到页面上还是乱码。从数据的"行走"路径看,编码格式都是统一的,应该没有问题,抓狂!难道是url设置的转码没起作用?难道是tomcat对请求自动设置了其它编码?难道跟linux操作系统编码有关?第一种情况最有可能,我找到管服务器的人员,要求修改character_set_client=utf8,结果吃了闭门羹:公司数据库设置都是统一的,不能随便修改;况且以前项目使用的数据库也是这样的设置,可以在程序中解决乱码。对于第二个问题,也是公司服务器上的tomcat,我知道会得到什么回答了,也就不再自讨没趣。对于第三问题,从页面输入和显示的数据,应该跟操作系统没有关系吧,再说了这个改起来更费劲,只是做个参考。继续抓狂!静下心来,从我在代码中用jdbc直接insert into 表 values(中文)这个测试看,跟web传输过程中的编码没有关系,我决定把问题锁定在建立连接时转码问题。又仔细查了几遍,发现我在使用Proxool建立连接池时使用的是properties文件,而原有项目使用的是xml文件,恍然大悟,转码方式不能照搬!于是把
?? ?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
中的amp;全部去掉,重试,页面上出现了笑容灿烂的汉字。高兴!

二.为了这么个简单的问题,查阅了大量资料,从结果上看,并没有直接上用的,可是感觉收获颇多,相信对jsp和mysql乱码的问题又有了进一步的认识。
?1.mysql中关于字符集的种类有很多,对我们编程有影响的主要是客户端字符集(character_set_client)和数据库字符集(character_set_database)在写入时Mysq会将客户端指定的字符集转换成数据库字符集存入数据文件,读取时又将数据库字符集转换成客户端指定的字符集展示给客户端,把客户端字符集和数据库字符设置一致,显而易见的好处是免掉转换的性能损耗;另外,如果考虑到以后数据库的迁移,将数据库字符集设置为大多数数据库都支持的字符集会省掉很大麻烦。
?
??1>.客户端字符集的设置有这么几种方法:
?? ?A. 使用控制台连接,在my.ini文件中的client项里面设置;?
?? ?B. 使用ems连接,优先使用ems连接配置的字符集,默认使用my.ini文件中的设置;?
?? ?C. jdbc连接,在连接串中指定:
? jdbc:mysql://192.168.0.10:3306/test?useUnicode=true&characterEncoding=utf-8
??2>.几个有关mysql命令行字符集相关的命令
?? ?A. 查看 MySQL 数据库服务器字符集,数据库字符集和客户端字符集?
?? ? ? show variables like '%char%';?
+--------------------------+----------------------------------------+
| character_set_client ? ? | latin1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | 客户端字符集?
| character_set_connection | latin1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |?
| character_set_database ? | utf8 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | 数据库字符集
| character_set_filesystem | binary ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |?
| character_set_results ? ?| latin1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |?
| character_set_server ? ? | latin1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | 服务器字符集?
| character_set_system ? ? | utf8 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |?
| character_sets_dir ? ? ? | /usr/local/mysql/share/mysql/charsets/ |?

B. 查看 MySQL 数据表(table) 的字符集?

show table status from tablename like '%countries%';?

C. 查看 MySQL 数据列(column)的字符集。?

show full columns from tablename;?

D. 查看当前安装的 MySQL 所支持的字符集。?

show char set;

?2.我们对数据库的操作无非就是存取数据,在这一过程中,乱不乱码和数据库字符集好像没有什么关系。我们只要保证写入时选择的字符集和读取时选择的字符集一致,即只需保证两次操作的客户端字符集一致并且该字符集支持所存取的数据字符即可.