使用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)。
+--------------------+--------------+------+-----+---------+----------------+
| 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的:
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();
}请注意,我最初的实现没有包含
?useUnicode=yes&characterEncoding=UTF-8但是,增加它并不能使它变得更好或更糟。我想这可能是罪魁祸首。我还尝试了latin1,而不是utf-8,看看这是否产生了不同,但没有运气,结果是完全一样的,即,它的结果是C-3,ras,‰,圣保罗。
我甚至尝试过这样的方法:
byte[] rowBytes = row.getBytes("name");
String utfdecocedStr = new String(rowBytes, "UTF-8");
System.out.println(utfdecocedStr);但输出仍为C-圣保罗‰ireann
在python中,我不执行任何解码/编码,查询和连接都是基本的,并且得到正确的字符串。我是否需要在DB或Java方面完成一个步骤才能使其正常工作?在my.conf中,我没有任何设置来设置任何编码配置。
Python方法:
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
我在数据库上运行了以下命令,并找到了以下配置,这可能解释了我所看到的行为:
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添加以下内容:
character-set-server = utf8
character-set-filesystem = utf8然后,表演变为:
mysql>显示诸如‘字符%’这样的变量;
+--------------------------+---------------------------------------------+
| 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控制台上发出了命令:
ALTER DATABASE <dbname> CHARACTER SET utf8;显示像‘字符%’这样的变量;
+--------------------------+---------------------------------------------+
| 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 |
+----------------------+-----------------+不幸的是,这仍然未能解决这一问题。
有人能让我知道如何在不清除数据库的情况下纠正这个问题吗?
发布于 2015-08-12 19:11:33
首先,我意识到我使用的表编码为UTF-8,但是输入到它的源表是latin1,这证实了我对编码的怀疑。
为将数据从一个复制到另一个而编写代码的人没有进行编码转换,因此我觉得数据已经损坏了编码。
我进行了各种实验,包括将数据库连接到
?useUnicode=yes&characterEncoding=UTF-8我还在SQL控制台上播放了以下内容:
SET character_set_client=latin1;
SET character_set_connection=latin1;
SET character_set_database=latin1;
SET character_set_results=latin1;以及播放my.cnf和设置的变化:
[mysqld]
character-set-server = utf8
character-set-filesystem = utf8不管怎么说,这些都没有帮助。最后,为了证明这不是java问题,而是一个损坏的数据集,我用UTF8编码创建了自己的表,将名称存储在其中,并让我的程序提取数据。看上去是对的。所以现在这是一个修正原始表格内容的问题。
我唯一不能解释的是python程序如何没有将其标记为一个问题。这不是我第一次因为Java的强类型而遇到python的宽恕,在这些情况下,这是一种祝福和痛苦。
==============================
更新2015/08/19:
当我将源表固定到UTF8并正确地存储数据时,Java代码工作了,但是python代码崩溃了。
为了在python中修复它,我只添加了
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驱动程序处理这个问题时,它没有工作:
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找到的最新的
发布于 2015-08-28 04:42:24
你有Mojibake。
SET NAMES latin1 (或set_charset('latin1')或.)。(应该是utf8。)CHARACTER SET latin1。(也可能是从表/数据库继承的。)(应该是utf8。)CHARACTER SET utf8,但应该是这样。如果需要对数据进行修复,则需要一个“2步修改”,如下所示
ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;https://stackoverflow.com/questions/31933574
复制相似问题