Mysql 在项目中应用注意事项
一、mysql字符集乱码的问题
(http://imysql.cn/charset_tips)建议,数据库字符集尽量使用utf8(HTML页面对应的是utf-8),以使你的数据能很顺利的实现迁移,因为utf8字符集是目前最适合于实现多种不同字符集之间的转换的字符集,尽管你在命令行工具上可能无法正确查看数据库中的内容,我依然强烈建议使用utf8作为默认字符集.
1、分析涉及到的字符集
(1)安装数据库时的编码集
(2)创建数据库时的编码集
(3)排序时校验字符集
(4)connection连接层字符集
2、默认的配置从何而来呢?(http://linux.chinaunix.net/bbs/archiver/tid-943550.html )
编译 MySQL 时,指定了一个默认的字符集,这个字符集是 latin1;
安装 MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的;
启动 mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的;
此时 character_set_server 被设定为这个默认的字符集;
当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为 character_set_server;
当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集;
在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集;
当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集;
这个字符集就是数据库中实际存储数据采用的字符集,mysqldump 出来的内容就是这个字符集下的。
简单的总结一下,如果什么地方都不修改,那么所有的数据库的所有表的所有栏位的都用 latin1 存储,不过我们如果安装 MySQL,一般都会选择多语言支持,也就是说,安装程序会自动在配置文件中把 default_character_set 设置为 UTF-8,这保证了缺省情况下,所有的数据库的所有表的所有栏位的都用 UTF-8 存储。
3、分析乱码出现的环节以及给与解决
二、示例
1、新建数据库表情形
(1).创建数据库
CREATE DATABASE IF NOT EXISTS test_charset default charset utf8 COLLATE utf8_general_ci;
#注意后面这句话 "COLLATE utf8_general_ci",大致意思是在排序时根据utf8校验集来排序
#那么在这个数据库下创建的所有数据表的默认字符集都会是utf8了
(2)创建数据表
create table test_bean(
id int(11) NOT NULL auto_increment,
name varchar(100),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#这句话就是创建一个表了,制定默认字符集为utf8
(3)c3p0配置文件的连接字符串设置(连接数据库的url中一定要指定编码类型)
jdbc:mysql://localhost:3306/test_charset?useUnicode=true&characterEncoding=UTF-8
(4)Hibernate方言的配置
<!-- <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<!-- <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLMyISAMDialect </prop> -->
(5)、客户端命令行显示的设置
客户端使用默认设置和使用“SET NAMES 'utf8';”后,都显示乱码;使用 “SET NAMES 'gb2312';” 显示正常。
每次登录客户端的数据库,都要执行,否则还是乱码。
注意:1-4步骤按照上述设置后,java应用可以显示正常,按照5设置后,命令行控制台显示正常。
2、现存数据库表的情形
附1:旧数据升级办法
以原来的字符集为latin1为例,升级成为utf8的字符集。原来的表: old_table (default charset=latin1),新表:new_table(default charset=utf8)。
第一步:导出旧数据
mysqldump --default-character-set=latin1 -hlocalhost -uroot -B my_db --tables old_table > old.sql
第二步:转换编码(类似unix/linux环境下)
iconv -t utf-8 -f gb2312 -c old.sql > new.sql
或者可以去掉 -f 参数,让iconv自动判断原来的字符集
iconv -t utf-8 -c old.sql > new.sql
在这里,假定原来的数据默认是gb2312编码。
第三步:导入
修改old.sql,在插入/更新语句开始之前,增加一条sql语句:
"SET NAMES utf8;"
,保存。
mysql -hlocalhost -uroot my_db < new.sql
大功告成!!
修改字段的编码:
ALTER TABLE `test` CHANGE `dd` `dd` VARCHAR( 45 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
资料引用:http://www.knowsky.com/344632.html
三、项目遇到异常的解决
1、No identifier specified for entity ....?
解决:实体bean中没有设置以下信息。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
2、Connections could not be acquired from the underlying database!
解决:(参考laoer的配置)
c3p0配置文件的连接字符串设置(连接数据库的url中一定要指定编码类型)
jdbc:mysql://localhost:3306/test_charset?useUnicode=true&characterEncoding=UTF-8
同时Hibernate方言的配置
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
四、附录:查看mysql数据库字符集
查看系统的字符集和排序方式的设定可以通过下面的两条命令:
SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
7 rows in set (0.00 sec)
SHOW VARIABLES LIKE 'collation_%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)
上面列出的值就是系统的默认值。
SET NAMES 'gb2312';
设置客户端相关字符集
它相当于下面的三句指令:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
参阅网址:
http://linux.chinaunix.net/bbs/archiver/tid-943550.html