2010-07-18 6 views
31

comme le titre dit, j'ai un problème entre java et mysqlJava + Mysql UTF8 problème

La base de données mysql, tables et colonnes sont utf8_unicode_ci. J'ai une application qui a une entrée d'un xml, puis composez 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 renvoie 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); 

à la fois avec s.execyte et s.executeUpdate les caractères spéciaux sont stockés en tant que?

donc caractère spécial ne sont pas stockés correctement: מסירות קצרות est stocké sous forme ?????????

Hi! est stocké sous forme Hi!

Un conseil?

Merci

+1

Comment lisez-vous le code source XML? Est-ce que ça vient d'un fichier ou est-ce une chaîne d'un service web, ou autre chose? Il est possible que votre lecture originale du fichier XML provoque le problème. –

+0

c'est une chaîne d'un webservice, j'utilise db.parse ("http: // ......") pour obtenir le contenu xml ... – Marcx

Répondre

72

Solved J'ai oublié d'ajouter le codage lors de l'initialisation de connexion:

avant était:

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

maintenant (travail):

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

+0

ne devrait-il pas être utf8? https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html – tObi

11

AUGH!

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

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

Définir toutes mes internes « NE PAS FAIRE CE » alarmes.

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

Au lieu de créer le texte SQL, s'il vous plaît refactorisons votre code afin que vous finissez 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(); 

C'est, nous la DB échapper le texte. S'il vous plaît, à moins qu'un jour vous voulez avoir une conversation comme this one. Comme un 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 d'autre mentionné, il est très possible que les choses se foirent lorsque vous lisez du XML)

+0

ouais je sais, j'ai écrit de cette façon pour vous donner un code plus léger;) – Marcx

+0

lol. Je peux comprendre un commentaire de côté, mais une réponse rapide sur le pauvre garçon? -1 – kellogs

+0

@DanielMartin +1, existe-t-il un moyen d'obtenir la chaîne de requête finale de 'pstmt' après avoir défini toute sa valeur, j'ai besoin de le savoir pour pouvoir consigner la requête en cours d'exécution. – Watt