Saya memiliki nilai string berikut: "walmart obama π½π"
Saya menggunakan MySQL dan Java.
Saya mendapatkan pengecualian berikut: `java.sql.SQLException: Nilai string salah: '\ xF0 \ x9F \ x91 \ xBD \ xF0 \ x9F ...'
Berikut adalah variabel yang saya coba masukkan:
var1 varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL`
Kode Java saya yang mencoba memasukkan "walmart obama π½π" adalah preparedStatement. Jadi saya menggunakan setString()
metode ini.
Sepertinya masalahnya adalah pengkodean nilai π½π. Bagaimana cara memperbaikinya? Sebelumnya saya menggunakan Derby SQL dan nilainya π½π baru saja menjadi dua sqaures (saya pikir ini adalah representasi dari karakter nol)
Semua bantuan sangat dihargai!
java
mysql
encoding
character-encoding
sqlexception
CodeKingPlusPlus
sumber
sumber
CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Jawaban:
Apa yang Anda miliki
EXTRATERRESTRIAL ALIEN (U+1F47D)
danBROKEN HEART (U+1F494)
yang tidak berada dalam bidang multibahasa dasar. Mereka bahkan tidak dapat direpresentasikan di java sebagai satu karakter"π½π".length() == 4
,. Mereka jelas bukan karakter nol dan orang akan melihat kotak jika Anda tidak menggunakan font yang mendukungnya.MySQL
utf8
hanya mendukung pesawat dasar multibahasa, dan Anda perlu menggunakanutf8mb4
gantinya :Jadi untuk mendukung karakter ini, MySQL Anda harus 5,5+ dan Anda harus menggunakannya di
utf8mb4
mana saja. Pengkodean koneksi perlu dilakukanutf8mb4
, kumpulan karakter perluutf8mb4
dan pengumpulan harus dilakukanutf8mb4
. Untuk java masih saja"utf-8"
, tapi MySQL membutuhkan perbedaan.Saya tidak tahu driver apa yang Anda gunakan tetapi cara driver agnostik untuk mengatur charset koneksi adalah dengan mengirim kueri:
Tepat setelah membuat koneksi.
Lihat juga ini untuk Connector / J :
Sesuaikan juga kolom dan database Anda:
Sekali lagi, versi MySQL Anda harus relatif mutakhir untuk dukungan utf8mb4.
sumber
utf8mb4
, sepertinya Anda masih menggunakanutf8_general_ci
..Do not issue the query set names with Connector/J, as the driver will not detect that the character set has changed, and will continue to use the character set detected during the initial connection setup.
Secara keseluruhan, untuk menyimpan simbol yang membutuhkan 4 byte, Anda perlu memperbarui kumpulan karakter dan pemeriksaan
utf8mb4
:alter table <some_table> convert to character set utf8mb4 collate utf8mb4_unicode_ci
Di lingkungan pengembangan saya untuk # 2, saya lebih suka mengatur parameter pada baris perintah saat memulai server:
mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
btw, perhatikan perilaku Connector / J dengan
SET NAMES 'utf8mb4'
:Dan hindari mengatur
characterEncoding
parameter di url koneksi karena akan menggantikan encoding server yang dikonfigurasi:sumber
Anehnya, saya menemukan bahwa MENGHAPUS
&characterEncoding=UTF-8
dariJDBC url
melakukan trik bagi saya dengan masalah serupa.Berdasarkan properti saya,
Saya rasa ini mendukung apa yang dikatakan @Esailija di atas, yaitu MySQL saya, yang memang 5,5, sedang mencari tahu citarasa favoritnya sendiri dari pengkodean UTF-8.
(Catatan, saya juga menentukan
InputStream
I'm reading from sepertiUTF-8
pada kode java, yang mungkin tidak sakit) ...sumber
useUnicode=true
bahkan tidak dibutuhkan? Dalam kasus saya, satu-satunya yang berhasil adalah pengaturancharacter_set_server=utf8mb4
global di server (grup parameter RDS) dan TIDAK memiliki characterEncoding di URL JDBC.Bagaimana saya memecahkan masalah saya.
Saya punya
Di url koneksi jdbc hibernate saya dan saya mengubah tipe data string menjadi teks panjang dalam database, yang sebelumnya varchar.
sumber
Tambahkan baris
useUnicode=true&characterEncoding=UTF-8
ke url jdbc Anda.Dalam kasus Anda, data tidak sedang dikirim menggunakan
UTF-8
pengkodean.sumber
Saya menghadapi masalah yang sama dan menyelesaikannya dengan mengatur Collation ke utf8_general_ci untuk setiap kolom.
sumber
Saya kira MySQL tidak percaya ini menjadi teks UTF8 yang valid. Saya mencoba menyisipkan pada tabel uji dengan definisi kolom yang sama (koneksi klien mysql juga UTF8) dan meskipun melakukan penyisipan, data yang saya ambil dengan klien MySQL CLI serta JDBC tidak mengambil nilai dengan benar. Untuk memastikan UTF8 berfungsi dengan benar, saya memasukkan "ΓΆ" alih-alih "o" untuk obama:
Aplikasi java kecil untuk diuji dengan:
Keluaran:
Juga, saya telah mencoba sisipan yang sama dengan koneksi JDBC dan itu memberikan pengecualian yang sama seperti yang Anda dapatkan. Saya yakin ini adalah bug MySQL. Mungkin sudah ada laporan bug tentang situasi seperti itu ..
sumber
Saya memiliki masalah yang sama dan setelah berhati-hati terhadap semua rangkaian karakter dan menemukan bahwa semuanya baik-baik saja, saya menyadari bahwa properti yang disadap yang saya miliki di kelas saya diberi anotasi sebagai @Column alih-alih @JoinColumn (javax.presistence; hibernate) dan itu menghancurkan segalanya.
sumber
menjalankan
temukan character-set-server jika bukan utf8mb4.
setel di my.cnf Anda, seperti
tambahkan satu baris
akhirnya restart mysql
sumber
character_set_server
adalah opsinya, TIDAKcharacter-set-server
Pengaturan ini useOldUTF8Behavior = true berfungsi dengan baik untuk saya. Itu tidak memberikan kesalahan string yang salah tetapi itu mengubah karakter khusus seperti Γ menjadi beberapa karakter dan disimpan dalam database.
Untuk menghindari situasi seperti itu, saya menghapus properti ini dari parameter JDBC dan alih-alih mengubah tipe data kolom saya ke BLOB. Ini bekerja dengan sempurna.
sumber
Selain itu, tipe data bisa menggunakan blob install varchar atau text.
sumber