Java 在MySQL表中插入希伯来语字符时得到问号

Java 在MySQL表中插入希伯来语字符时得到问号,java,mysql,jsp,jdbc,hebrew,Java,Mysql,Jsp,Jdbc,Hebrew,我正在使用Netbeans构建一个web应用程序,它使用Java、JSP处理带有希伯来语字段的数据库 DDL如下所示: String cityTable = "CREATE TABLE IF NOT EXISTS hebrew_test.table (" +"id int(11) NOT NULL AUTO_INCREMENT," +"en varchar(30) NOT NULL,"

我正在使用Netbeans构建一个web应用程序,它使用Java、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   אבג
我试过了,但那不是同一个问题。我在表格中得到了问号


我还将表定义在
UTF8\u bin
中,正如您在上面的代码中看到的那样。

您将值直接包含到SQL中。那总是个坏主意。使用
PreparedStatement
,参数化SQL,并将值设置为参数。它可能无法解决问题,但这肯定是第一件要尝试的事情,因为您无论如何都应该使用参数化SQL。(参数化SQL可避免代码与数据分离,并避免不必要的转换。)

接下来,您应该准确地找出问题真正发生的位置:

  • 确保您尝试插入的值是正确的
  • 检查您检索的值是否正确
  • 使用检查web响应中的内容-检查声明的编码和实际数据中的内容
检查值时,应迭代字符串中的每个字符,并将值作为UTF-16代码单元打印出来(在循环中使用
tocharray()
charAt()
)。仅将值打印到控制台就有太多可能出现其他问题

编辑:了解一下我为什么写这篇文章作为答案:

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

所有这些都是向前移动OP的一种重要方式,而不仅仅是在类似注释的请求中获取更多信息。

您需要告诉JDBC驱动程序在将代表SQL查询的字符解码为字节时使用UTF-8编码。您可以通过向JDBC连接URL添加
useUnicode=yes
characterEncoding=UTF-8
查询参数来实现这一点

jdbc:mysql://localhost:3306/db_name?useUnicode=yes&characterEncoding=UTF-8
否则,它将使用操作系统平台默认字符集。MySQL JDBC驱动程序本身非常清楚客户端(JDBC代码运行的地方)和服务器端(DB表所在的地方)中使用的编码。DB表使用的字符集未包含的任何字符都将替换为问号

另见:

您使用的是什么数据库?(还有,它是“水管工”)。我使用SQL数据库,这是构建db:_语句.executeUpdate(“如果不存在,则创建数据库prodb”)的代码;谢谢Jon,我发现:@MatanTouti:我不会说这是一个伟大的页面-错误的异常处理,没有资源清理,等等。。。更好一些,尽管仍然不完美…我尝试插入的值是正确的,通过调试器(验证是否足够好?):allprofessions=“插入到prodb.professions(id,profession,professionEn)值(1,'其他',(2,'电工',(3,'电工','其他')。我得到的值实际上是我上面显示的表。我不知道如何检查网络响应。。我认为答案更像是UTF 8的声明(我猜)。@MatanTouti:好吧,正如我所说的-使用Wireshark来准确地了解响应中的内容。如果您以前没有使用过Wireshark,那么现在是学习的好时机-所有web开发人员都应该知道如何查看网络上的内容…im运行的服务器是localhost,带有xampp。我能用wireshark检查一下它的本地主机吗?你是最好的,我的朋友!!!我已经寻找解决办法很久了。更改了几乎所有的字符集和排序规则:D非常感谢!