Issue: MySQL数据库存储的中文为乱码
Env: Deiban + MySQL 5.1.47
1、MySQL字符集
查看当前MySQL服务器支持的所有字符集
mysql> SHOW CHARACTER SET;
任何一个给定的字符集至少有一个校对规则。它可能有几个校对规则。
列出一个字符集的校对规则
mysql> SHOW COLLATION LIKE 'ucs2%'; mysql> SHOW COLLATION LIKE 'utf8%';
校对规则命名约定:它们以其相关的字符集名开始,通常包括一个语言名,并且以_ci (大小写不敏感)、_cs (大小写敏感)或_bin (二元)结束。
查看当前字符集设置
mysql> show variables like 'character_set_%'; mysql> show variables like 'collation_%';
修改数据库的字符集
mysql>use dbname mysql>alter database dbname character set utf8 collate utf8_general_ci;
创建数据库指定数据库的字符集
mysql>create database dbname character set utf8;
或者通过配置文件修改:
修改/var/lib/mysql/dbname/db.opt
default-character-set=latin1
default-collation=latin1_swedish_ci
为
default-character-set=utf8
default-collation=utf8_general_ci
然后重起MySQL。
修改MySQL的表的字符集
mysql> alter table table_name default character set utf8 collate utf8_general_ci;
服务器使用character_set_client 变量作为客户端发送的查询中使用的字符集。
服务器接收到查询后应该转换为哪种字符集?
服务器使用character_set_connection 和collation_connection 系统变量。它将客户端发送的查询从character_set_client 系统变量转换到character_set_connection (除 非字符串文字具有象_latin1 或_utf8 的引介词)。
服务器发送结果集或返回错误信息到客户端之前应该转换为哪种字符集?
character_set_results 变量指示服务器返回查询结果到客户端使用的字符集。包括结果数据,例如列值和结果 元数据(如列名)。
字符集转换流程
client(如servlet)发送一个查询 -> 服务器收到查询,将查询串从character_set_client 转换到character_set_connection,然后执行转换后的查询 -> 服务器将结果数据转换到character_set_results字符集后发送回客户端。
调整这些变量的设置
有两个语句影响连接字符集:
SET NAMES 'charset_name'
SET CHARACTER SET charset_name
SET NAMES 显示客户端发送的SQL 语句中使用什么字符集。因此,SET NAMES 'cp1251' 语句告诉服务器“将来从这个客户端传来的信息采用字符集 cp1251” 。 它还为服务器发送回客户端的结果指定了字符集。(例如,如果你使用一个SELECT 语句, 它 表示列值使用了什么字符集。)
SET NAMES 'x ' 语句与这三个语句等价:
mysql> SET character_set_client = x; mysql> SET character_set_results = x; mysql> SET character_set_connection = x;
将x 设置为character_set_connection 也就设置了collation_connection 是x 的默认校对规则。
SET CHARACTER SET 语句是类似的,但是为 默认数据库设置连接字符集和校对规则。SET CHARACTER SET x 语句与这三个语句等价:
mysql> SET character_set_client = x; mysql> SET character_set_results = x; mysql> SET collation_connection = @@collation_database;
当一个客户端连接时,它向服务器发送希望使用的字符集名称。服务器为那个字符集设置character_set_client 、character_set_results 和 character_set_connection 变量。(实际上,服务器为使用该字符集执行一个SET NAMES 操作。)
对于mysql 客户端,如果你希望使用与默认字符集不同的字符集,不需要每次 启动时执行SET NAMES 语句。可以在mysql 语句行中或者选项文件中添加一个--default-character-set 选 项设置。例如,你每次运行mysql 时,以下的选项文件设置把三个字符集变量修改为koi8r:
[mysql]
default-character-set=koi8r
例如:假设column1 定义为CHAR(5) CHARACTER SET latin2 。如果没有设定SET NAMES 或SET CHARACTER SET SELECT column1 FROM t ,当连接后,服务器使用客户端指定的字符集返回列column1 的所有值。 另一方面,如果你设定SET NAMES 'latin1' 或SET CHARACTER SET latin1 ,那么发送结果之前,服务器转换latin2 值到latin1 。 转换可能会丢失那些不属于两种字符集的字符。 ,那么对于
如果不希望服务器执行任何转换,设置character_set_results 为NULL :
mysql> SET character_set_results = NULL;
使用JDBC连结MySQL时,可以在URL中指定字符集
jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=GBK
URL在xml配置文件中的写法:
jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=GBK
& 是& 的转义字符。
2、解决方法
(1) 修改/etc/mysql/my.cnf,加入:
[mysqld]
default-character-set = gbk
init_connect = 'SET NAMES gbk'
[client]
default-character-set = gbk
(2)在JDBC连结串中指定字符集为GBK
jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=GBK