2010-07-18 16 views
31

come dice il titolo, ho un problema tra Java e MySQLJava + Mysql UTF8 Problema

Il DB MySQL, le tabelle e colonne sono utf8_unicode_ci. Ho un'applicazione che ha avuto qualche input da un xml, quindi comporre la query ...

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

questo metodo restituisce un array di stringa che contiene uno o più inserto SQL Query ... poi

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

entrambi con s.execyte e s.executeUpdate i caratteri speciali sono memorizzati come?

quindi carattere speciale non vengono memorizzati in modo corretto: מסירות קצרות viene memorizzato come ?????????

Hi! viene memorizzato come Hi!

Qualche consiglio?

Grazie

+1

Come stai leggendo l'XML di origine? Proviene da un file o è una stringa da un servizio Web o qualcos'altro? È possibile che la lettura originale del xml stia causando il problema. –

+0

è una stringa da un webservice, io uso db.parse ("http: // ......") per ottenere il contenuto xml ... – Marcx

risposta

72

risolto, Ho dimenticato di aggiungere la codifica durante l'inizializzazione di connessione:

prima era:

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

ora (di lavoro):

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

+0

non dovrebbe essere utf8? https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html – tObi

11

AUGH!

Va bene, quindi, questo non è direttamente la cosa che hai chiesto, ma questo:

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

partì tutto il mio interno "non farlo" allarmi.

Hai il controllo assoluto e completo sul testo in arrivo? Sei sicuro che qualcuno non avrà un apostrofo nel testo in arrivo, nemmeno per caso?

Invece di creare testo SQL, si prega di refactoring del codice in modo che si finisce per chiamare:

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

Cioè, lasciare che il DB sfuggire al testo. Per favore, a meno che un giorno tu voglia avere una conversazione come this one. Come effetto collaterale vantaggioso, questo approccio può risolvere, assumendo che i valori di stringa siano ancora corretti quando li si legge dall'XML. (Come menzionato da qualcun altro, è molto probabile che le cose si incasinino quando si legge dall'XML)

+0

sì, lo so, ho scritto in questo modo per darti un codice più leggero;) – Marcx

+0

lol. Riesco a capire un commento laterale ma una risposta soddisfacente al povero ragazzo? -1 – kellogs

+0

@DanielMartin +1, c'è un modo per ottenere la stringa di query finale da 'pstmt' dopo aver impostato tutto il suo valore, ho bisogno di saperlo in modo che possa registrare quale query è stata eseguita. – Watt