2010-07-18 6 views
31

như tiêu đề cho biết, tôi gặp sự cố giữa java và mysqlJava + Mysql UTF8 Vấn đề

Mysql DB, bảng và cột là utf8_unicode_ci. Tôi có một ứng dụng mất một số đầu vào từ một xml, sau đó soạn truy vấn ...

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

phương pháp này trả về một mảng các chuỗi có chứa một hay nhiều truy vấn SQL chèn ... sau đó

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

cả hai với s.execytes.executeUpdate các ký tự đặc biệt được lưu dưới dạng?

trở nên đặc biệt char không được lưu trữ một cách chính xác: מסירות קצרות được lưu giữ như ?????????

Hi! được lưu giữ như Hi!

Bất cứ lời khuyên?

Cảm ơn

+1

Bạn đang đọc XML nguồn như thế nào? Nó đến từ một tập tin hay nó là một chuỗi từ một dịch vụ web, hay cái gì khác? Có thể bạn đọc bản gốc của xml đang gây ra sự cố. –

+0

đó là một chuỗi từ một webservice, tôi sử dụng db.parse ("http: // ......") để lấy nội dung xml ... – Marcx

Trả lời

72

Giải Quyết, Tôi quên để thêm mã hóa khi khởi tạo kết nối:

trước là:

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

bây giờ (làm việc):

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

+0

không nên là utf8? https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html – tObi

11

AUGH!

Được rồi, vì vậy, đây không phải là trực tiếp điều bạn yêu cầu, nhưng điều này:

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

Đặt tắt tất cả nội bộ của tôi "XIN ĐỪNG LÀM THẾ" báo động.

Bạn có quyền kiểm soát tuyệt đối và hoàn toàn đối với văn bản đến không? Bạn có chắc chắn một người nào đó sẽ không có dấu nháy đơn trong văn bản đến, thậm chí một cách tình cờ không?

Thay vì tạo ra văn bản SQL, xin vui lòng refactor code của bạn để bạn kết thúc cuộc gọi:

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

Đó là, chúng ta hãy DB thoát khỏi văn bản. Xin vui lòng, trừ khi một ngày nào đó bạn muốn có một cuộc trò chuyện như this one. Là một tác dụng phụ thuận lợi, cách tiếp cận này có thể giải quyết vấn đề của bạn, giả sử rằng các giá trị chuỗi vẫn chính xác khi bạn đọc chúng từ XML. (Như một người khác đã đề cập, rất có thể mọi thứ đang bị rối tung lên khi bạn đọc từ XML)

+0

vâng tôi biết, tôi đã viết theo cách này để cung cấp cho bạn một mã nhẹ hơn;) – Marcx

+0

lol. Tôi có thể hiểu một lời bình luận bên cạnh nhưng không biết trả lời câu trả lời cho người nghèo? -1 – kellogs

+0

@DanielMartin +1, có cách nào để nhận chuỗi truy vấn cuối cùng từ 'pstmt' sau khi bạn đặt tất cả giá trị của nó không, tôi cần biết rằng để tôi có thể ghi lại truy vấn nào đang thực thi. – Watt