latin1 java_使用Java读写存储在latin1编码的MySQL中的UTF-8编码的中文

latin1 java_使用Java读写存储在latin1编码的MySQL中的UTF-8编码的中文绝大多数情况下 一个项目中 都是使用同一套编码 如 全部使用 UTF 8 或者 GBK 但是当涉及到多个项目合并 新手加入等情况时 不可避免出现使用多套编码的情况 所有字符串都是英文的情况还好 若是出现了中文 就导致了乱码的出现 下面以我碰到的问题的解决方案说明 前置说明 JavaMySQLUTF 8utf8ISO 8859 1l

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

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

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

前置说明:

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

Java            MySQL

UTF-8          utf8

ISO-8859-1 latin1

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

MySQL数据库使用latin1的编码,导入导出的数据是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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221889.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午5:03
下一篇 2026年3月17日 下午5:03


相关推荐

  • java面试问题大全及答案大全word,逆袭面经分享

    java面试问题大全及答案大全word,逆袭面经分享一、对象的实例化1.创建对象的方式new:最常见的方式(本质是构造器)变形1:Xxx的静态方法变形2:XxBuilder/XxoxFactory的静态方法Class的newInstance():反射的方式,只能调用空参的构造器,权限必须是publicConstructor的newInstance(Xxx):反射的方式,位于java.lang.reflect.Constructor可以调用空参、带参的构造器,权限没有要求使用clone():不调用任何构造器,当前类需

    2022年7月7日
    29
  • 【Java】MD5加盐加密

    【Java】MD5加盐加密MD5 加密 MD5 是常用的加密算法 在用户注册时通过算法加密的密码存入数据库 保护用户密码 数据库管理员不能直接看见密码 即使用户数据库被盗 没有存储明文的密码对用户来说也多了一层安全保障 用户登录时 在客户端用户输入密码后 也会使用 MD5 进行加密 这样即使用户的网络被窃听 窃听者依然无法拿到用户的原始密码 MD5 加盐加密把参数名和参数值拼接成一个字符串 同时把给定的密钥也拼接起来 之所以需要

    2025年6月26日
    8
  • STM32Cubemx ADC配置详解

    STM32Cubemx ADC配置详解标题 STM32CubemxA 配置详解 ADC 独立模式所谓独立模式 在一个管脚上只有一个 ADC 采集该管脚的电压 ADC 双重模式所谓两重模式 就是 ADC1 IN0 ADC2 IN0 在同一管脚上 采集的是同一管脚上的电压 ADC 三重模式所谓三重模式 ADC1 IN0 ADC2 IN0 ADC3 IN0 在同一管脚上 采集的是同一管脚上的电压 ParameterSet

    2026年3月17日
    2
  • 世界古代史帝国_世界历史上最富有的帝国

    世界古代史帝国_世界历史上最富有的帝国 西方史书上记载的每个世纪最强大的国家               公元前15世纪:埃及王国        公元前14世纪:埃及王国、赫梯王国(并列)        公元前13世纪:埃及王国、商王国(并列)        公元前12世纪:埃及王国        公元前11世纪:(空缺)        公元前10世纪:周王国        公元前9世纪:亚述帝国        公

    2026年2月20日
    5
  • 安全狗云备份客户端小版本更新v1.0.05502

    安全狗云备份客户端小版本更新v1.0.05502

    2021年8月25日
    65
  • MySQL 的COUNT(x)性能怎么样?

    做一个积极的人编码、改bug、提升自己我有一个乐园,面向编程,春暖花开!文章目录0 说明1 总结2 拓展x 可以代表: 主键id、字段、1、*0 说明对于count(主键id)来说innodb引擎会遍历整张表,把每一行的id值都取出来,返回给server层,server层判断id值不为空,就按行累加对于count(字段)来说如果这个字段定义为not null,一行行的从记…

    2022年2月28日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号