web-dev-qa-db-fra.com

Java + Problème Mysql UTF8

comme le dit le titre, j'ai un problème entre Java et mysql

La base de données mysql, les tables et les colonnes sont utf8_unicode_ci. J'ai une application qui a pris une entrée d'un xml, puis compose la requête ...

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;
}

cette méthode retourne un tableau de String qui contient une ou plusieurs requêtes d'insertion SQL ... puis

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

les deux avec s.execyte et s.executeUpdate les caractères spéciaux sont stockés sous?

donc les caractères spéciaux ne sont pas stockés correctement: מסירות קצרות est stocké en tant que ?????????

Hi! est stocké en tant que Hi!

Aucun conseil?

Merci

36
Marcx

Résolu, j'ai oublié d'ajouter l'encodage lors de l'initialisation de la connexion:

avant était:

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

maintenant (fonctionne):

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

91
Marcx

AUGH!

D'accord, ce n'est pas directement la chose que vous avez demandée, mais ceci:

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

Déclenchez toutes mes alarmes internes "NE FAITES PAS CECI".

Avez-vous un contrôle absolu et complet sur le texte entrant? Êtes-vous sûr que quelqu'un n'aura pas d'apostrophe dans le texte entrant, même par accident?

Au lieu de créer du texte SQL, veuillez refactoriser votre code pour que vous finissiez par appeler:

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();

Autrement dit, laissez la DB échapper au texte. S'il vous plaît, sauf si un jour vous voulez avoir une conversation comme celle-ci . En tant qu'effet secondaire avantageux, cette approche peut résoudre votre problème, en supposant que les valeurs de chaîne sont toujours correctes lorsque vous les lisez à partir du XML. (Comme quelqu'un l'a mentionné, il est très possible que les choses se gâchent lorsque vous lisez à partir du XML)

11
Daniel Martin