Mam następującą wartość ciągu: „walmart obama 👽💔”
Używam MySQL i Java.
Otrzymuję następujący wyjątek: `java.sql.SQLException: Niepoprawna wartość ciągu: '\ xF0 \ x9F \ x91 \ xBD \ xF0 \ x9F ...'
Oto zmienna, do której próbuję wstawić:
var1 varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL`
Mój kod Java, który próbuje wstawić „walmart obama 👽💔”, jest przygotowanym oświadczeniem. Więc używam setString()
metody.
Wygląda na to, że problemem jest kodowanie wartości 👽💔. Jak mogę to naprawić? Wcześniej używałem Derby SQL, a wartości 👽💔 skończyły się na dwóch kwadratach kwadratowych (myślę, że jest to reprezentacja znaku null)
Każda pomoc jest mile widziana!
java
mysql
encoding
character-encoding
sqlexception
CodeKingPlusPlus
źródło
źródło
CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Odpowiedzi:
To, co masz, jest,
EXTRATERRESTRIAL ALIEN (U+1F47D)
aBROKEN HEART (U+1F494)
czego nie ma na podstawowym planie wielojęzyczności. Nie mogą być one nawet w Javie reprezentowana jako jeden char"👽💔".length() == 4
. Zdecydowanie nie są to znaki puste i jeśli nie używasz czcionek, które je obsługują, zobaczysz kwadraty.MySQL
utf8
obsługuje tylko podstawową płaszczyznę wielojęzyczną, autf8mb4
zamiast tego musisz użyć :Aby obsługiwać te znaki, Twój MySQL musi mieć wersję 5.5+ i musisz go używać
utf8mb4
wszędzie. Konieczne jest kodowanie połączeniautf8mb4
, zestaw znakówutf8mb4
i kolakcjautf8mb4
. W przypadku javy to nadal tylko"utf-8"
kwestia, ale MySQL wymaga rozróżnienia.Nie wiem, jakiego sterownika używasz, ale niezależnym od sterownika sposobem ustawienia zestawu znaków połączenia jest wysłanie zapytania:
Zaraz po nawiązaniu połączenia.
Zobacz także to dla złącza / J :
Dostosuj również kolumny i bazę danych:
Twoja wersja MySQL musi być stosunkowo aktualna, aby obsługiwać utf8mb4.
źródło
utf8mb4
, wygląda na to, że nadal używaszutf8_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.
Podsumowując, aby zapisać symbole wymagające 4 bajtów, należy zaktualizować zestaw znaków i sortowanie dla
utf8mb4
:alter table <some_table> convert to character set utf8mb4 collate utf8mb4_unicode_ci
W moim środowisku programistycznym dla # 2 wolę ustawiać parametry w wierszu poleceń podczas uruchamiania serwera:
mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
btw, zwróć uwagę na zachowanie złącza / J z
SET NAMES 'utf8mb4'
:I unikaj ustawiania
characterEncoding
parametru w adresie URL połączenia, ponieważ zastąpi to skonfigurowane kodowanie serwera:źródło
Co dziwne, odkryłem, że USUWANIE
&characterEncoding=UTF-8
zJDBC url
z podobnymi problemami.Na podstawie moich właściwości
Myślę, że to potwierdza to, co powiedział @Esailija powyżej, tj. Mój MySQL, który jest rzeczywiście 5.5, odkrywa swój własny ulubiony smak kodowania UTF-8.
(Uwaga, określam również, z
InputStream
którego czytam, jakUTF-8
w kodzie java, co prawdopodobnie nie boli) ...źródło
useUnicode=true
nawet nie jest potrzebny? W moim przypadku jedyne, co zadziałało, to ustawieniecharacter_set_server=utf8mb4
globalne na serwerze (grupa parametrów RDS) i NIE posiadanie żadnego kodowania znaków w adresie URL JDBC.Jak rozwiązałem swój problem.
miałem
W moim hibernacyjnym adresie URL połączenia jdbc i zmieniłem typ danych ciągu na longtext w bazie danych, który wcześniej był varchar.
źródło
Dołącz linię
useUnicode=true&characterEncoding=UTF-8
do adresu URL jdbc.W Twoim przypadku dane nie są przesyłane za pomocą
UTF-8
kodowania.źródło
Napotkałem ten sam problem i rozwiązałem go, ustawiając Collation na utf8_general_ci dla każdej kolumny.
źródło
Myślę, że MySQL nie uważa tego za poprawny tekst UTF8. Wypróbowałem wstawianie na tabeli testowej z tą samą definicją kolumny (połączenie klienta mysql było również UTF8) i chociaż wstawiło to, dane pobrane przez klienta MySQL CLI, a także JDBC nie pobrały poprawnie wartości. Aby upewnić się, że UTF8 działa poprawnie, wstawiłem „ö” zamiast „o” dla obamy:
Mała aplikacja Java do przetestowania z:
Wynik:
Ponadto wypróbowałem tę samą wkładkę z połączeniem JDBC i wyrzuciła ten sam wyjątek, który otrzymujesz. Uważam, że to błąd MySQL. Może jest już raport o błędzie dotyczący takiej sytuacji ..
źródło
Miałem podobny problem i po uważnym sprawdzeniu wszystkich zestawów znaków i stwierdzeniu, że są w porządku, zdałem sobie sprawę, że błędna właściwość, którą miałem w mojej klasie, została oznaczona jako @Column zamiast @JoinColumn (javax.presistence; hibernate) i to wszystko zrywało.
źródło
wykonać
znajdź serwer zestawu znaków, jeśli nie jest to utf8mb4.
ustaw go w swoim my.cnf, na przykład
dodaj jedną linię
w końcu uruchom ponownie mysql
źródło
character_set_server
jest opcją, NIEcharacter-set-server
To ustawienie useOldUTF8Behavior = true działało dobrze dla mnie. Nie dawał nieprawidłowych błędów w łańcuchach, ale konwertował znaki specjalne, takie jak Ã, na wiele znaków i zapisywał w bazie danych.
Aby uniknąć takich sytuacji, usunąłem tę właściwość z parametru JDBC i zamiast tego przekonwertowałem typ danych mojej kolumny na BLOB. To działało idealnie.
źródło
Poza tym typ danych może używać instalacji typu blob varchar lub text.
źródło