Java + Mysql UTF8 问题

2022-09-01 04:08:12

正如标题所说,我在java和mysql之间有问题

mysql DB、表和列utf8_unicode_ci。我有一个应用程序,它从xml中获取了一些输入,然后编写查询...

public String [] saveField(String xmltag, String lang){     
  NodeList nodo = this.doc.getElementsByTagName(xmltag);
  String [] pos = new String[nodo.getLength()];     
  for (int i = 0 ; i < nodo.getLength() ; i++ ) {
     Node child = nodo.item(i);
     pos[i] =  "INSERT INTO table (id, lang, value) VALUES (" +
        child.getAttributes().getNamedItem("id").getNodeValue().toString() + " , " +
        lang + " , " + 
        "'" + child.getFirstChild().getTextContent() + "'" +
        ");";       
    }   
   return pos;
}

此方法返回一个 String 数组,其中包含一个或多个 SQL 插入查询...然后

Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection("jdbc:mysql:///dbname", "user", "pass");
.....
Statement s; s =
this.con.createStatement ();
s.execute(query);

带有字符和特殊字符都存储为 ?s.execytes.executeUpdate

所以特殊字符没有正确存储:存储为מסירות קצרות?????????

Hi!存储为Hi!

有什么建议吗?

谢谢


答案 1

解决了初始化连接时忘记添加编码的问题:

之前是:

con = DriverManager.getConnection("jdbc:mysql:///dbname", "user", "pass");

现在(工作):

con = DriverManager.getConnection("jdbc:mysql:///dbname?useUnicode=true&characterEncoding=utf-8", "user", "pass");


答案 2

哎呀!

好吧,所以,这不是你直接要求的东西,而是这个:

 pos[i] =  "INSERT INTO table (id, lang, value) VALUES (" +
    child.getAttributes().getNamedItem("id").getNodeValue().toString() + " , " +
    lang + " , " + 
    "'" + child.getFirstChild().getTextContent() + "'" +
    ");";       

触发我所有内部的“不要这样做”警报。

您是否对传入的文本有绝对和完全的控制权?您确定有人在传入的文本中不会有撇号,即使是偶然的吗?

请不要创建 SQL 文本,而是重构代码,以便最终调用:

PreparedStatement pstmt =
    con.prepareStatement("INSERT INTO table (id, lang, value) VALUES (?,?,?)");
// then, in a loop:
pstmt.setString(0, child.getAttributes().getNamedItem("id").getNodeValue().toString());
pstmt.setString(1, lang);
pstmt.setString(2, child.getFirstChild().getTextContent());
pstmt.execute();

也就是说,让 DB 转义文本。拜託,除非有一天你想進行這樣的對話。作为一个有利的副作用,此方法可以解决您的问题,假定从 XML 读取字符串值时字符串值仍然正确。(正如其他人提到的,当您从XML读取时,事情很可能会变得混乱)