首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MYSQL查询编码的字符串在Java中损坏

使用MYSQL查询编码的字符串在Java中损坏
EN

Stack Overflow用户
提问于 2015-08-11 05:01:09
回答 2查看 1.6K关注 0票数 1

使用MYSQL查询编码的字符串在Java中损坏

使用Java,我连接到一个MYSQL数据库,在那里我查询一个表,从中收集一个字段。

该字段具有UTF8编码文本,即:

Córas ireann

当我登录到MYSQL控制台并查看表中的该行时,上面的文本就是我所看到的。部署的mysql版本是: mysql Ver 14.14 Distrib 5.1.52,用于使用readline5.1的未知-linux-gnu (x86_64)。

如果我使用python程序连接到同一个数据库,查询相同的表并得到相同的行,则文本看起来是正确的,即它是Córas ireann。

但是,当我通过Java查询它时,文本显示为:

圣保罗‰ireann

我怀疑这是西方的(ISO latin1),但我不确定,只是猜测。

我做了一个显示表状态,并看到我正在查询的表有utf8_general_ci的排序规则。

我正在查询的表没有任何加载项编码定义,字段名称是varchar(512)。

代码语言:javascript
复制
+--------------------+--------------+------+-----+---------+----------------+
| Field              | Type         | Null | Key | Default | Extra          |
+--------------------+--------------+------+-----+---------+----------------+
| id                 | int(11)      | NO   | PRI | NULL    | auto_increment |
| name               | varchar(512) | YES  |     | NULL    |                |

我导入的SQL connect JAR是mysql java-5.1.36,我也尝试了v5.1.34和5.0.8,但这没有什么区别。

我就是这样连接到DB的:

代码语言:javascript
复制
    String dbStr =
    String.format("jdbc:mysql://%s:%d/%s?useUnicode=yes&characterEncoding=UTF-8", LOCAL_MYSQL_HOST,
                                       LOCAL_MYSQL_PORT, LOCAL_MYSQL_DB);
    try {
        cdb = DriverManager.getConnection(dbStr, LOCAL_MYSQL_USER, LOCAL_MYSQL_PASS);
        Statement dbStatement = cdb.createStatement();
        String query = String.format("SELECT name FROM customer WHERE id=%d",customerId);
        ResultSet row = dbStatement.executeQuery(query);
        if (row.first()) {
             System.out.println("name is " + row.getString("name");
        }
    } catch (SQLException exc) {
        exc.printStackTrace();
    }

请注意,我最初的实现没有包含

代码语言:javascript
复制
?useUnicode=yes&characterEncoding=UTF-8

但是,增加它并不能使它变得更好或更糟。我想这可能是罪魁祸首。我还尝试了latin1,而不是utf-8,看看这是否产生了不同,但没有运气,结果是完全一样的,即,它的结果是C-3,ras,‰,圣保罗。

我甚至尝试过这样的方法:

代码语言:javascript
复制
                byte[] rowBytes = row.getBytes("name");
                String utfdecocedStr = new String(rowBytes, "UTF-8");
                System.out.println(utfdecocedStr);

但输出仍为C-圣保罗‰ireann

在python中,我不执行任何解码/编码,查询和连接都是基本的,并且得到正确的字符串。我是否需要在DB或Java方面完成一个步骤才能使其正常工作?在my.conf中,我没有任何设置来设置任何编码配置。

Python方法:

代码语言:javascript
复制
  import MySQLdb
  cdb = MySQLdb.connect(host=LOCAL_MYSQL_HOST,port=LOCAL_MYSQL_PORT,
                         user=LOCAL_MYSQL_USER,
                         passwd=LOCAL_MYSQL_PASS,db=LOCAL_MYSQL_DB)
  ccursor = self.cdb.cursor()
  query = """SELECT name FROM customer WHERE id='%d' """%(customer_id)
  row = ccursor.execute(query)
  if row:
      customername = ccursor.fetchone()

谢谢you...Amro

-更新20150811

我在数据库上运行了以下命令,并找到了以下配置,这可能解释了我所看到的行为:

代码语言:javascript
复制
show variables like 'character%';
+--------------------------+---------------------------------------------+
| Variable_name            | Value                                       |
+--------------------------+---------------------------------------------+
| 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                                        |
| character_sets_dir       | /usr/share/percona-xtradb-cluster/charsets/ |
+--------------------------+---------------------------------------------+
8 rows in set (0.00 sec)

mysql> show variables like 'collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)

通过向my.cnf添加以下内容:

代码语言:javascript
复制
character-set-server = utf8
character-set-filesystem = utf8

然后,表演变为:

mysql>显示诸如‘字符%’这样的变量;

代码语言:javascript
复制
+--------------------------+---------------------------------------------+
| Variable_name            | Value                                       |
+--------------------------+---------------------------------------------+
| character_set_client     | utf8                                        |
| character_set_connection | utf8                                        |
| character_set_database   | latin1                                      |
| character_set_filesystem | utf8                                        |
| character_set_results    | utf8                                        |
| character_set_server     | utf8                                        |
| character_set_system     | utf8                                        |
| character_sets_dir       | /usr/share/percona-xtradb-cluster/charsets/ |
+--------------------------+---------------------------------------------+


+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | utf8_general_ci   |
+----------------------+-------------------+

因此,我在DB控制台上发出了命令:

代码语言:javascript
复制
 ALTER DATABASE <dbname> CHARACTER SET utf8;

显示像‘字符%’这样的变量;

代码语言:javascript
复制
+--------------------------+---------------------------------------------+
| Variable_name            | Value                                       |
+--------------------------+---------------------------------------------+
| character_set_client     | utf8                                        |
| character_set_connection | utf8                                        |
| character_set_database   | utf8                                        |
| character_set_filesystem | utf8                                        |
| character_set_results    | utf8                                        |
| character_set_server     | utf8                                        |
| character_set_system     | utf8                                        |
| character_sets_dir       | /usr/share/percona-xtradb-cluster/charsets/ |
+--------------------------+---------------------------------------------+
8 rows in set (0.00 sec)

mysql> show variables like 'collation%';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database   | utf8_general_ci |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+

不幸的是,这仍然未能解决这一问题。

有人能让我知道如何在不清除数据库的情况下纠正这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-12 19:11:33

首先,我意识到我使用的表编码为UTF-8,但是输入到它的源表是latin1,这证实了我对编码的怀疑。

为将数据从一个复制到另一个而编写代码的人没有进行编码转换,因此我觉得数据已经损坏了编码。

我进行了各种实验,包括将数据库连接到

代码语言:javascript
复制
?useUnicode=yes&characterEncoding=UTF-8

我还在SQL控制台上播放了以下内容:

代码语言:javascript
复制
SET character_set_client=latin1;
SET character_set_connection=latin1;
SET character_set_database=latin1;
SET character_set_results=latin1;

以及播放my.cnf和设置的变化:

代码语言:javascript
复制
[mysqld] 
character-set-server = utf8 
character-set-filesystem = utf8

不管怎么说,这些都没有帮助。最后,为了证明这不是java问题,而是一个损坏的数据集,我用UTF8编码创建了自己的表,将名称存储在其中,并让我的程序提取数据。看上去是对的。所以现在这是一个修正原始表格内容的问题。

我唯一不能解释的是python程序如何没有将其标记为一个问题。这不是我第一次因为Java的强类型而遇到python的宽恕,在这些情况下,这是一种祝福和痛苦。

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

更新2015/08/19:

当我将源表固定到UTF8并正确地存储数据时,Java代码工作了,但是python代码崩溃了。

为了在python中修复它,我只添加了

代码语言:javascript
复制
self.cdb = MySQLdb.connect(host=LOCAL_MYSQL_HOST,port=LOCAL_MYSQL_PORT,
                         user=LOCAL_MYSQL_USER, 
  passwd=LOCAL_MYSQL_PASS,
  db=LOCAL_MYSQL_DB,use_unicode=True,charset="UTF8")

这解决了这个问题。

不幸的是,当我之前尝试使用Java驱动程序处理这个问题时,它没有工作:

代码语言:javascript
复制
dbStr = String.format("jdbc:mysql://%s:%d/%s?useUnicode=yes&characterEncoding=latin1", esConfig.LOCAL_MYSQL_HOST, esConfig.LOCAL_MYSQL_PORT, esConfig.LOCAL_MYSQL_DB);

我使用的是java 1.7.80,jdbc包是mysql-连接器-java-5.1.36-bin.jar,这是我从Oracle找到的最新的

票数 1
EN

Stack Overflow用户

发布于 2015-08-28 04:42:24

你有Mojibake

  • 客户端中的字节被正确地用utf8编码(很好)。
  • 在默认情况下,您可能连接到SET NAMES latin1 (或set_charset('latin1')或.)。(应该是utf8。)
  • 表中的列声明为CHARACTER SET latin1。(也可能是从表/数据库继承的。)(应该是utf8。)
  • 表中的列可能是或可能不是CHARACTER SET utf8,但应该是这样。

如果需要对数据进行修复,则需要一个“2步修改”,如下所示

代码语言:javascript
复制
ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31933574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档