将希伯来字符插入MySQL表时获取问号

时间:2013-01-01 18:15:12

标签: java mysql jsp jdbc hebrew

我正在使用Netbeans使用Java来构建Web应用程序,JSP使用希伯来字段处理数据库。

DDL如下:

String cityTable = "CREATE TABLE IF NOT EXISTS hebrew_test.table ("
                            +"id int(11) NOT NULL AUTO_INCREMENT,"
                            +"en varchar(30) NOT NULL,"
                            +"he varchar(30) COLLATE utf8_bin NOT NULL,"
                            +"PRIMARY KEY (id)"
                            +") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;";
String insert = "INSERT INTO hebrew_test.table (en, he) VALUES ('A','a')";
String insert2 = "INSERT INTO hebrew_test.table (en, he) VALUES ('B','ב')";
String insert3 = "INSERT INTO hebrew_test.table (en, he) VALUES ('C','אבג')";


executeSQLCommand(cityTable);
executeSQLCommand(insert);
executeSQLCommand(insert2);
executeSQLCommand(insert3);

我得到的输出表格:

1   A   a
2   B   ?
3   C   ???

而不是:

1   A   a
2   B   ב
3   C   אבג

我试过Hebrew appears as question marks in Netbeans,但这不是同一个问题。我在表格中得到了问号。

我也将表格定义为UTF8_bin,如上面的代码所示。

2 个答案:

答案 0 :(得分:7)

您需要告诉JDBC驱动程序在将表示SQL查询的字符解码为字节时使用UTF-8编码。您可以通过将useUnicode=yescharacterEncoding=UTF-8查询参数添加到JDBC连接URL来实现此目的。

jdbc:mysql://localhost:3306/db_name?useUnicode=yes&characterEncoding=UTF-8

否则将使用操作系统平台默认字符集。 MySQL JDBC驱动程序本身非常了解客户端(运行JDBC代码的位置)和服务器端(DB表所在的位置)中使用的编码。 DB表使用的字符集未覆盖的任何字符都将被问号替换。

另见:

答案 1 :(得分:2)

您将值直接包含在SQL中。这总是一个坏主意。使用PreparedStatement参数化SQL,并将值设置为参数。它可能无法解决问题 - 但它绝对是第一个尝试的东西,因为你应该使用参数化的SQL。 (参数化SQL避免使用SQL injection attacks,将代码与数据分开,并避免不必要的转换。)

接下来,您应该确切地确定问题的确切位置:

  • 确保您尝试插入的值正确无误。
  • 检查检索的值是否正确。
  • 使用Wireshark检查网络回复中的内容 - 检查声明的编码实际数据中的内容

检查值时,应迭代字符串中的每个字符,并将值打印为UTF-16代码单元(使用toCharArray()或在循环中使用charAt())。只是将值打印到控制台会留下太多其他问题的可能性。

编辑:关于为什么我写这个作为答案的一个小背景:

  • 根据我的经验,包括字符串值作为参数而不是直接插入SQL,有时可以避免此类问题(当然,出于安全原因,这样做会更好)。
  • 根据我的经验,诊断问题是在数据库端还是在网络端也很重要。最好通过记录正在使用的UTF-16代码单元来完成此诊断,而不仅仅是字符串(因为在日志记录或控制台输出期间可能会出现进一步的编码问题)。
  • 根据我的经验,插入读取代码路径时很容易发生这样的问题。

所有这一切对于推动OP前进非常重要,而不仅仅是在类似注释的请求中获取更多信息。