Chinaunix首页 | 论坛 | 博客
  • 博客访问: 529746
  • 博文数量: 135
  • 博客积分: 3568
  • 博客等级: 中校
  • 技术积分: 1942
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-19 17:52
文章分类

全部博文(135)

文章存档

2012年(29)

2011年(41)

2010年(26)

2009年(12)

2008年(9)

2007年(12)

2006年(6)

分类: Java

2007-06-06 16:02:40

写在前面:如果大家的MySQL中使用的是GBK或UTF-8,但是在Windows下的命令行中查看中文数据的时候是乱码,则请先执行以下语句,在进行增删改查:

mysql> SET NAMES GBK;

乱码原因:中文Windows的CMD只支持GBK编码,但是MySQL中是UTF-8编码,不匹配。

此外,如果MySQL在安装的时候选择多语言支持,那么你稍后创建Schema,Table时,无论指定的编码是GBK,还是UTF-8,貌似都一样,它内部都是使用UTF-8或UNICODE存储的 --- 推测啦,未调查。



/* mysql JDBC 乱码原因探究 参考: mysql文档第10章: Character Set Support 写在前面以方便那些没有耐心看完全文的朋友: 解决方法: 无论在mysql的配置是什么字符集, 在创建表(或创建数据库)的时候都明确的指定字符集 如: create table test (....) DEFAULT CHARACTER SET utf8; 在使用 JDBC 的时候都明确指定字符集参数: 如: jdbc:mysql://localhost/test?useunicode=true&characterEncoding=utf8 mysql 有4个字符集设定级别: 服务器级别: 通过编译时指定或在配置文件中通过default-character-set(有两处)指定 数据库级别: CREATE DATABASE db_name [[DEFAULT] CHARACTER SET charset_name] [[DEFAULT] COLLATE collation_name] ALTER DATABASE db_name [[DEFAULT] CHARACTER SET charset_name] [[DEFAULT] COLLATE collation_name] 表级别: CREATE TABLE tbl_name (column_list) [DEFAULT CHARACTER SET charset_name [COLLATE collation_name]] ALTER TABLE tbl_name [DEFAULT CHARACTER SET charset_name] [COLLATE collation_name] 列级别: col_name {CHAR | VARCHAR | TEXT} (col_length) [CHARACTER SET charset_name [COLLATE collation_name]] 补充说明: 1> 对于上述sql格式中的COLLATE是只得是排序的方法(比如是否大小写敏感排序), 这里只讨论字符集的设定. 2> 可以用show character set;来查看MySql中可用的字符集 当然, 以上4个级别的字符集设定从上往下是适用面越来越窄, 但优先级越来越高. 以下是对比说明表, 假设直接用JDBC插入含有汉字的记录. 服务器字符集 列字符集 JDBC URL参数 现象 汉字输入解决方法 latin1 latin1 无 乱码 string.getBytes() utf8 无 乱码 无法恢复 gbk 无 乱码 无法恢复 latin1 有 运行异常 string.getBytes() utf8 有 正常 gbk 有 正常 utf8 latin1 无/有 运行异常 string.getBytes() utf8 无/有 正常 gbk 无/有 正常 说明: JDBC URL参数是指 ?useunicode=true&characterEncoding=gbk 或 ?useunicode=true&characterEncoding=utf8 运行异常是指 SQLException: Data too long for column string.getBytes()是指: 插入数据库是用 new String(name.getBytes(oneCharSet),iso) 而读取数据库时用 new String(rs.getString("color").getBytes(iso), oneCharSet) 注意: 1> 若列字符集正常且又用了 String.getBytes(), 则会运行异常! 2> 命令行窗口用的是OS默认字符集GBK, 故对于列字符集为urf8的显示会是乱码, 对列字符集为gbk的也是乱码, 则不知原因! */ import java.io.*; import java.sql.*; import java.lang.*; public class T{ static String user="root"; static String passwd="123456"; static String gbk = "gbk"; static String iso = "ISO-8859-1"; static String utf = "utf-8"; static String url="jdbc:mysql://localhost/test";//?useunicode=true&characterEncoding=utf8 static String driver = "org.gjt.mm.mysql.Driver"; public static void main(String[] args){ Connection conn = null; try { Class.forName(driver).newInstance(); conn = DriverManager.getConnection(url, user, passwd); String name = "张亮亮"; String addr = "哈工大(威海)"; String *** = "男"; String color = "蓝"; Statement stmt = conn.createStatement(); String dropSql = "drop table if exists std "; String createSql = "create table std ( " + " name varchar(32) CHARACTER SET latin1," + " *** varchar(32) CHARACTER SET gbk," + " addr varchar(32) CHARACTER SET utf8," + " color varchar(32) " + ");"; String insertSql = "insert into std values('张亮亮"//+new String(name.getBytes(),iso) + "','男"//+new String(***.getBytes(),iso) + "','哈工大(威海)"//+new String(addr.getBytes(), iso) + "','蓝"//+new String(color.getBytes(),iso) + "')"; String selectSql = "select * from std"; stmt.executeUpdate( dropSql ); //drop table stmt.executeUpdate( createSql ); //create table stmt.executeUpdate( insertSql ); //insert //label_1: ResultSet rs = stmt.executeQuery(selectSql); while(rs.next()){ System.out.println(rs.getString("name")); //label_2: +", "+new String(rs.getString("name").getBytes(iso)) System.out.println(rs.getString("***")); //label_3: +", "+new String(rs.getString("***").getBytes(iso)) System.out.println(rs.getString("addr")); //label_4: +", "+new String(rs.getString("addr").getBytes(iso)) System.out.println(rs.getString("color")); //label_5: +", "+new String(rs.getString("color").getBytes(iso)) } } catch (Exception e){ e.printStackTrace(); } } }; /* 详细测试 OS: windows 2003 系统字符集: GBK mysql 版本: 5.0 1> my.ini 中 default-character-set=utf8 JDBC URL : jdbc:mysql://localhost/test 或者 jdbc:mysql://localhost/test?useunicode=true&characterEncoding=utf8 或者 jdbc:mysql://localhost/test?useunicode=true&characterEncoding=gbk insertSql: insert into std values('张亮亮','男','哈工大(威海)','蓝')" lable_1: 运行异常: Data too long for column 'name' at row 1 原因: latin1无法存储汉字, 用 'zhangliangliang' 代替 '张亮亮', 除了修改列的存储字符集尚无解决方案 lable_2: zhangliangliang lable_3: 男 label_4: 哈工大(威海) label_5: 蓝 Mysql 命令行结果: mysql> select * from std; +-----------------+------+-------------------+-------+ | name | *** | addr | color | +-----------------+------+-------------------+-------+ | zhangliangliang | 鐢? | 鍝堝伐澶?濞佹捣) | 钃? | +-----------------+------+-------------------+-------+ 1 row in set (0.00 sec) 2> my.ini 中 default-character-set=latin1 JDBC URL : jdbc:mysql://localhost/test?useunicode=true&characterEncoding=utf8 或者 jdbc:mysql://localhost/test?useunicode=true&characterEncoding=gbk insertSql: insert into std values('张亮亮','男','哈工大(威海)','蓝')" lable_1: 运行异常: Data too long for column 'name' at row 1 Data too long for column 'color' at row 1 解决方法见最后: 目前先用拼音 zhangliangliang 代替. lable_2: zhangliangliang lable_3: 男 label_4: 哈工大(威海) label_5: 同lable_1, 用blue代替继续测试. mysql> select * from std; +-----------------+------+---------+-------+ | name | *** | addr | color | +-----------------+------+---------+-------+ | zhangliangliang | ? | ???(??) | blue | +-----------------+------+---------+-------+ 1 row in set (0.03 sec) JDBC URL : jdbc:mysql://localhost/test insertSql: insert into std values('张亮亮','男','哈工大(威海)','蓝')" lable_1: 运行无异常 lable_2: ??? lable_3: ? label_4: ???(??) label_5: ? mysql> select * from std; +------+------+---------+-------+ | name | *** | addr | color | +------+------+---------+-------+ | ??? | ? | ???(??) | ? | +------+------+---------+-------+ 1 row in set (0.00 sec) 对于 列字符集为utf8(如addr列), latin1(明确设定(如name列)或默认(如color列))有如下解决方法 (其他UNICODE格式未测试, 用GBK也会出现类似运行时异常): 写入时用:new String(addr.getBytes(), iso) 读取时用:new String(rs.getString("addr").getBytes(iso)) 并且在命令行窗口也可以正确显示!(毕竟命令行下只用系统字符集) */
function winOnLoad_startColor(){ /*由于彩色显示需要给定的CSS文件支持, 而link标签在UCBLOG的源代码编辑时会被 自动删除,所以只能通过Javascript载入css文件*/ var linkElement = document.createElement('link'); linkElement.setAttribute("type", "text/css"); linkElement.setAttribute("rel", "stylesheet"); linkElement.setAttribute("href", ""); document.body.appendChild(linkElement); dp.SyntaxHighlighter.HighlightAll('code'); } /*由于此时body还没有完全载入, 所以用onload事件触发来正确完成着色*/ window.attachEvent("onload", winOnLoad_startColor);
阅读(2700) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-04-10 10:57:23

您这个可帮了我一个大忙! 正愁数据库乱码问题,看了后,清醒了不少