mysql latin1 utf8 java_Java读写以latin1编码存储以UTF-8输出的MySQL数据库(中文乱码)...

绝大多数情况下,一个项目中,都是使用同一套编码。如,全部使用UTF-8或者GBK。

但是当涉及到多个项目合并、新手加入等情况时,不可避免出现使用多套编码的情况。所有字符串都是英文的情况还好,若是出现了中文,就导致了乱码的出现。

下面以我碰到的问题的解决方案说明。

前置说明:

==============

Java MySQL

UTF-8 utf8

ISO-8859-1 latin1

==============

MySQL数据库使用latin1的编码,导入导出的数据是UTF-8编码的(即其与java端的交互是utf-8编码格式的),即将MySQL当做一个透明的存储。

============================

character_set_client latin1

character_set_connection latin1

character_set_database latin1

character_set_filesystem binary

character_set_results latin1

character_set_server latin1

character_set_system utf8

=============================

Java编写的导入数据程序(包括查看数据校验,即涉及到数据的导入导出)

C++编写的导出数据程序(仅涉及到数据的导出)

Java程序如何读写中文

第一种解决办法:

0

.Java文件设置为UTF-8编码(Eclipse的设置方法为:点击Window->Preferences->General->Workspace->Text

file encoding->Other 填入UTF-8)

1

.设置URL参数characterEncoding为utf8。示例:jdbc:mysql://127.0.0.1:3306?characterEncoding=utf8

2 .所有的数据库连接在执行任何SQL语句之前,先执行SQL语句set names

'latin1'

3 .取数据时,需要从ISO-8859-1转码。本项目示例为:new

String(rs.getString("SampleColumnName").getBytes("ISO-8859-1"),

"UTF-8")

为什么这样解决?

0

.对于写在*.java文件中的中文,它的编码方式就是文件的编码方式,设置为UTF-8,即写在*.java文件中的中文编码方式为UTF-8;

1

.对于从JDBC驱动程序发往服务器的所有字符串,缺省情况下均将自动地从原生的Java

Unicode形式转换为客户端字符编码。如果要转成特定编码,则需要设置characterEncoding,如要设置为UTF-8,则需要设置为characterEncoding=utf8

2 .set names

'latin1'主要是将以下三个字符集的编码方式改为latin1,即character_set_client、character_set_connection和character_set_results这三个的编码。当插入数据时,MySQL服务器把客户端传来的statement,从character_set_client字符集转换成character_set_connection字符集(除非字符串中有类似_latin1或者_utf8的字符集声明)。当查询数据时,character_set_results系统变量表明了服务器返回查询结果时使用的字符集。服务器返回的数据,有比如字段的值和元数据(例如字段名)。

由此,可以得出:

本项目中,SQL语句的编码是UTF-8;

URL参数characterEncoding设置的编码为SQL语句的编码;

在set names

'latin1'后,character_set_client为latin1,因此,JDBC会将SQL语句从UTF-8转化为latin1;

由于character_set_client和character_set_connection一致,所以MySQL服务器不做转换。

将SQL要求存储的数据存储在latin1的数据库中。

3

.取数据时,由于存储的数据和character_set_results的编码方式都为latin1,不做转码,取回后,由于显示中文要求UTF-8,所以需要转码为UTF-8。

但是,MySQL手册不建议我们这样使用。

第二种解决方法:

0 .Java文件设置为UTF-8编码

1

.设置URL参数characterEncoding为utf8。示例:jdbc:mysql://127.0.0.1:3306?characterEncoding=utf8

2

.所有SQL语句、尤其是含有中文的SQL语句都必须进行转码为ISO-8859-1。对于写在.java文件中的中文,由于文件是UTF-8编码的,转码示例如下:

String DesSql = new String(SrcSql.getBytes("UTF-8"),

"ISO-8859-1");

3 .取数据时,需要从ISO-8859-1转码。本项目示例为:new

String(rs.getString("SampleColumnName").getBytes("ISO-8859-1"),

"UTF-8")

为什么这样解决?尤其是2

,为什么可以代替set names 'latin1'?

2 .在没有设置set names 'latin1'的情况下,

============================

character_set_client utf8

character_set_connection utf8

character_set_database latin1

character_set_filesystem binary

character_set_results utf8

character_set_server latin1

character_set_system utf8

=============================

测试不使用set names和String转码时:

本项目中,SQL语句的编码是UTF-8;

URL参数characterEncoding设置的编码为SQL语句的编码;

由于没有set names

'latin1',character_set_client为utf-8,因此,JDBC会不会将SQL语句转码;

在传输SQL到MySQL后,由于传输的是utf-8的数据,存储到latin1是会报错的,测试结果如下:

=========================================================

java.sql.SQLException: Incorrect string value: '/xE4/xB8/xAD'

for column 'SampleColumnName' at row 1

at

com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)

at

com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)

at

com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)

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:2536)

at

com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2465)

at

com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:734)

at

org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)

at

org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)

=========================================================

编码问题,这样就走不下去了

只有将SQL中文更改编码。

String DesSql = new String(SrcSql.getBytes("UTF-8"),

"ISO-8859-1");

这样,将已经转码为latin1的SQL(也不会被JDBC转码)传输给MySQL服务器,服务器正常接收和存储。

Over

另:(下面的方法,我还没研究出该如何用)

convert(unhex(hex(convert(name using latin1))) using utf8) as

name

参考 http://t.sina.com.cn/1243233955/5en1gmTmOwC

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值