2012-03-08 59 views
5

Vì một số lý do lạ tôi dường như không thể thêm dữ liệu UTF-8 vào cơ sở dữ liệu MySQL của mình. Khi tôi nhập một ký tự không phải latin, nó được lưu dưới dạng ?????. Mọi thứ khác được lưu trữ tốt. Vì vậy, ví dụ, "đây là một ví dụ ® ™" được lưu trữ tốt, nhưng "和 英 辞典" được lưu trữ là "????".Không thể lưu trữ nội dung UTF-8 trong MySQL Sử dụng Java PreparedStatement

Url kết nối là tốt:

private DataSource getDB() throws PropertyVetoException { 
    ComboPooledDataSource db = new ComboPooledDataSource(); 
    db.setDriverClass("com.mysql.jdbc.Driver"); 
    db.setJdbcUrl("jdbc:mysql://domain.com:3306/db?useUnicode=true&characterEncoding=UTF-8"); 
    db.setUser("..."); 
    db.setPassword("..."); 
    return db; 
} 

Tôi đang sử dụng PreparedStatement như bạn mong đợi, tôi thậm chí đã cố gắng vào "đặt tên utf8" như ai đó đề nghị.

Connection conn = null; 
    PreparedStatement stmt = null; 
    ResultSet rs = null; 
    try { 
     conn = db.getConnection(); 

     stmt = conn.prepareStatement("set names utf8"); 
     stmt.execute(); 
     stmt = conn.prepareStatement("set character set utf8"); 
     stmt.execute(); 

        ... set title... 
     stmt = conn.prepareStatement("INSERT INTO Table (title) VALUES (?)"); 
     stmt.setString(1,title); 

     stmt.execute(); 
    } catch (final SQLException e) { 
    ... 

Bản thân bảng có vẻ ổn.

Default Character Set: utf8 
Default Collation: utf8_general_ci 
... 
Field title: 
Type text 
Character Set: utf8 
Collation: utf8_unicode_ci 

Tôi đã thử nghiệm bằng cách nhập vào Unicode ("和 英 辞典") thông qua trình chỉnh sửa GUI và sau đó chọn từ bảng - và nó đã được trả lại tốt. Vì vậy, điều này có vẻ là một vấn đề với JDBC.

Tôi đang thiếu gì?

+0

Bạn có chắc chắn rằng 'tựa đề' có nội dung phù hợp không? Có lẽ bạn đọc nó từ một tập tin bằng cách sử dụng ISO-bất cứ điều gì? –

+0

Có, khi tôi đặt một điểm ngắt trên tiêu đề tôi có thể thấy rằng nó thực sự unicode (ví dụ: 和 英 辞典) và không ???? – nostromo

+0

'utf8' là một chuỗi, do đó, kèm theo nó trong dấu ngoặc kép như:' "set names 'utf8'" '. Đừng gây rối với bộ ký tự. –

Trả lời

3

Có 2 điểm trong máy chủ mysql để kiểm tra để đặt đúng bộ ký tự UTF-8.

Database Cấp

này thu được bằng cách tạo ra nó:

CREATE DATABASE 'db' CHARACTER SET 'utf8'; 

Bảng Cấp

Tất cả các bảng cần phải được trong UTF-8 cũng (mà dường như phù hợp với bạn)

CREATE TABLE `Table1` (
    [...] 
) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; 

Phần quan trọng là DEFAULT CHARSET = utf8 đối chiếu = utf8_general_ci

Cuối cùng, nếu mã của bạn không được xử lý một cách chính xác utf8, bạn có thể buộc JVM của bạn để sử dụng mã hóa utf8 bằng cách thay đổi các thiết lập bằng cách khởi động:

java -Dfile.encoding=UTF-8 [...] 

hoặc thay đổi môi trường biến

"**JAVA_TOOLS_OPTIONS**" to -Dfile.encoding="UTF-8" 

hoặc lập trình bằng cách sử dụng:

System.setProperty("file.encoding" , "UTF-8"); 

(người cuối cùng này có thể không có tác dụng mong muốn kể từ khi JVM lưu trữ giá trị của mã hóa ký tự mặc định khi khởi động)

Hy vọng rằng sẽ giúp.

+0

đặt mã hóa mặc định cho jvm là hữu ích cho một số thứ, nhưng chắc chắn không bắt buộc phải lấy dữ liệu unicode vào và ra khỏi cơ sở dữ liệu. – jtahlborn

+0

dựa trên nhận xét của nostromo ngày hôm qua về điểm ngắt. Chúng ta có thể giả định rằng jvm của anh ta đã xử lý unicode một cách chính xác, vì vậy tôi đồng ý rằng nó không cần thiết trong trường hợp của anh ấy. – Kharaone

+0

Thực tế có ba cấp độ. Ngoài ra còn có mức kết nối: http://stackoverflow.com/questions/9283575/getting-incorrectly-encoded-characters-when-retrieving-values-from-mysql-db –

1

Nếu bạn đăng nhập vào cơ sở dữ liệu mysql và chạy show variables like 'character%'; , điều này có thể cung cấp một số thông tin chi tiết.

Vì bạn đang nhận tỷ lệ một byte một đối với dấu hỏi nên có khả năng kết nối đang thực hiện chuyển đổi bộ ký tự và thay thế ký tự Trung Quốc bằng ký tự thay thế cho byte đơn bộ.

5

Mở chuỗi kết nối JDBC của bạn, bạn chỉ cần thiết lập mã hóa charset như thế này:

jdbc: mysql: // localhost: 3306/dbname characterEncoding = utf8

3

Sử dụng stmt.setNString(...) thay vì stmt.setString(...).
Cũng đừng quên kiểm tra cột đối chiếu ở phía cơ sở dữ liệu.

+0

Bạn tiết kiệm một ngày của tôi. –

0

Cũng kiểm tra ngôn ngữ -a trên ubuntu mặc định Ubuntu hoạt động với ngôn ngữ en_us và không có ngôn ngữ khác được cài đặt. phải chỉ định characterEncoding = utf8 trong khi kết nối qua JDBC.

Các vấn đề liên quan