2010-07-18 62 views
31

como el título dice, tengo un problema entre Java y MySQLJava + MySQL UTF8 Problema

La base de datos MySQL, tablas y columnas son utf8_unicode_ci. tengo una aplicación que tomó algunas aportaciones de un xml, entonces componer la consulta ...

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

este método devuelve un array de cadenas que contiene una o más consultas SQL de inserción ... continuación

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

ambos con s.execyte y s.executeUpdate los caracteres especiales se almacenan como?

por lo Char especial no se almacenan correctamente: מסירות קצרות se almacena como ?????????

Hi! se almacena como Hi!

Algún consejo?

Gracias

+1

¿Cómo está leyendo el XML de origen? ¿Viene de un archivo o es una cadena de un servicio web, o alguna otra cosa? Es posible que la lectura original del xml esté causando el problema. –

+0

es una cadena de un servicio web, uso db.parse ("http: // ......") para obtener el contenido xml ... – Marcx

Respuesta

72

resuelto, me olvidó añadir la codificación en la inicialización de la conexión:

antes era:

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

ahora (de trabajo):

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

+0

¿no debería ser utf8? https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html – tObi

11

¡AUGH!

bien, así, esto no es directamente lo que solicitó, pero esto:

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

ponemos en marcha todo mi interior "NO hagas esto" alarmas.

¿Tiene control total y absoluto sobre el texto entrante? ¿Estás seguro de que alguien no tendrá un apóstrofo en el texto entrante, incluso por accidente?

En lugar de crear el texto SQL, refactorizar su código para que usted termina llamando a:

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

Es decir, dejar que el DB escapar el texto. Por favor, a menos que algún día quieras tener una conversación como this one. Como un efecto secundario ventajoso, este enfoque puede resolver su problema, suponiendo que los valores de cadena sigan siendo correctos cuando los lea desde el XML. (Como alguien más mencionó, es muy posible que las cosas se arruinen cuando lee en el XML)

+0

Sí, lo sé, escribí de esta manera para darle un código más ligero;) – Marcx

+0

lol. Puedo entender un comentario al margen pero ¿una respuesta al problema del pobre tipo? -1 – kellogs

+0

@DanielMartin +1, ¿hay alguna manera de obtener la cadena de consulta final de 'pstmt' después de establecer todo su valor, necesito saber eso para poder registrar qué consulta se estaba ejecutando. – Watt