Lösung für das Problem, dass Emoji-Ausdrücke nicht in MySQL eingefügt werden können

Lösung für das Problem, dass Emoji-Ausdrücke nicht in MySQL eingefügt werden können

Vorwort

Ich dachte immer, dass UTF-8 eine universelle Lösung für Zeichensatzprobleme sei, bis ich vor Kurzem auf dieses Problem gestoßen bin. Ich habe kürzlich an einem Crawler für Sina Weibo gearbeitet. Beim Speichern der Daten stellte ich fest, dass die folgende Ausnahme ausgelöst wurde, solange ich den Emoji-Ausdruck beibehielt:

Falscher Zeichenfolgenwert: „\xF0\x90\x8D\x83\xF0\x90...“

Wie wir alle wissen, ist UTF-8 3 Byte groß, was die meisten Schriftarten umfasst, die wir im täglichen Leben sehen. Aber 3 Byte reichen bei weitem nicht aus, um den gesamten Text aufzunehmen, daher wurde utf8mb4 erstellt. Utf8mb4 ist eine Obermenge von utf8, die 4 Byte einnimmt und abwärtskompatibel mit utf8 ist. Die Emoji-Ausdrücke, die wir im täglichen Leben verwenden, sind 4 Byte groß.

Also fügen wir hier Daten in die UTF-8-Tabelle ein und der Fehler Incorrect string value wird gemeldet.

Eine schnelle Google-Suche ergab die Lösung. Die konkrete Lösung lautet wie folgt:

1. Ändern Sie den Zeichensatz der Datentabelle auf utf8mb4

Das ist ganz einfach. Sie können online viele Änderungsanweisungen finden. Es wird jedoch empfohlen, die Tabelle neu zu erstellen, mysqldump -uusername -ppassword database_name table_name > table.sql zu verwenden, um die entsprechende Datentabelle zu sichern, und den Zeichensatz der Tabellenerstellungsanweisung auf utf8mb4 zu ändern. Importieren Sie dann das SQL erneut mysql -uusername -ppassword database_name < table.sql um den Vorgang zur Änderung des Zeichensatzes abzuschließen.

2. Die MySQL-Datenbankversion muss 5.5.3 oder höher sein

In allen Artikeln im Internet heißt es, dass nur MySQL 5.5.3 oder höher utf8mb4 unterstützt. Die von mir verwendete Datenbankversion war jedoch 5.5.18, und ich konnte das Problem schließlich lösen. Bitten Sie also nicht gleich den Wartungstechniker, die Datenbank zu aktualisieren. Versuchen Sie zunächst, das Problem selbst zu lösen.

3. Ändern Sie die Datenbankkonfigurationsdatei /etc/my.cnf und starten Sie den MySQL-Dienst neu

Der Hauptzweck besteht darin, den Standardzeichensatz der Datenbank sowie den Zeichensatz für Verbindung und Abfrage zu ändern. [MySQL unterstützt Emoji-Emoticons und aktualisiert die Kodierung auf UTF8MB4] [1] Dieser Artikel enthält detaillierte Einstellungsmethoden und [Detaillierte MySQL-Zeichensatzeinstellungen] [2] Dieser Artikel enthält die Funktionen jedes Zeichensatzes. Sie können ihn selbst lesen.

4. Aktualisieren Sie MySQL Connector auf 5.1.21 und höher

Von allen oben genannten Operationen ist Schritt 3 der kritischste, das Ändern der Datenbankkonfigurationsdatei, die wahrscheinlich ändert

[Kunde]
# Der Standardzeichensatz für Client-Quelldaten default-character-set = utf8mb4
[mysqld]
# Der Standardzeichensatz auf dem Server ist character-set-server=utf8mb4
# Standardzeichensatz der Verbindungsschicht collation-server=utf8mb4_unicode_ci
[mysql]
# Standardzeichensatz der Datenbank default-character-set = utf8mb4

Diese Konfigurationen geben die Zeichensätze an, die von den Pipelines verwendet werden, über die Daten vom Client zum Server weitergeleitet werden. Probleme mit einer dieser Pipelines können zu Einfügefehlern oder unleserlichen Zeichen führen.

In vielen Fällen kann die Online-Datenbank die Datenbankdateien jedoch nicht nach Belieben ändern. Daher lehnten unsere Kollegen von Betrieb und Wartung meine Anfrage zur Änderung der Datenbankkonfigurationsdatei (T_T) entschieden ab.

Die einzige Lösung besteht also darin, Code zu verwenden. Zunächst wollte ich mit dem Zeichensatz beginnen, der bei der Verbindung mit JDBC angegeben wurde.

jdbc:mysql://localhost:3306/ding?characterEncoding=UTF-8

Das Ändern von UTF-8 in utf8mb4 für die Java Style Charset-Zeichenfolge sollte das Problem hauptsächlich lösen, oder?

Leider verfügt Java JDBC nicht über einen Zeichensatz, der utf8mb4 entspricht. Bei Verwendung von UTF-8 ist es mit urf8mb4 kompatibel und konvertiert den Zeichensatz automatisch.

Um beispielsweise 4-Byte-UTF-8-Zeichensätze mit Connector/J zu verwenden, konfigurieren Sie den MySQL-Server mit character_set_server=utf8mb4 und lassen Sie characterEncoding aus der Connector/J-Verbindungszeichenfolge heraus. Connector/J erkennt dann automatisch die UTF-8-Einstellung. – [MySQL: Verwenden von Zeichensätzen und Unicode][3]

Später erfuhr ich, dass man in jeder Abfrageanforderung den zu verwendenden Zeichensatz explizit angeben kann. Mit set names utf8mb4 kann man den Zeichensatz dieser Verbindung als utf8mb4 angeben, aber diese Einstellung wird nach jeder Freigabe der Verbindung ungültig.

Die aktuelle Lösung besteht darin, set names utf8mb4 explizit aufzurufen und auszuführen, wenn Sie utf8mb4 einfügen müssen, wie zum Beispiel:

jdbcTemplate.execute("Namen festlegen utf8mb4");
jdbcTemplate.execute("...");

Es ist zu beachten, dass bei Verwendung des ORM-Frameworks das Framework das Committing aus Gründen der Leistungsoptimierung verzögert. Sofern die Transaktion nicht beendet wird oder der Benutzer aktiv ein erzwungenes Committing anfordert, werden set names utf8mb4 immer noch nicht wirksam.

Hier verwende ich myBatis und nehme MessageDao als Beispiel

// MessageDao
öffentliche Schnittstelle MessageDao {
 @Update("Namen festlegen utf8mb4")
 öffentliche void setCharsetToUtf8mb4();
 @Insert("in tb_message einfügen ......")
 öffentliche void insert(Nachricht msg);
}
// Testcode
SqlSession sqlSession = sqlSessioFactory.openSession();
messageDao = sqlSession.getMapper(MessageDao.class);
messageDao.setCharsetToUtf8mb4();
// Commit erzwingen sqlSession.commit();
messageDao.insert(Nachricht);

Bisher wurde das Problem gelöst.

Ach, wenn doch nur alles so reibungslos laufen könnte. Im Projekt wird die Mybatis-Instanz von Spring verwaltet, was bedeutet, dass ich die SQLSession nicht abrufen kann, was wiederum bedeutet, dass ich kein Commit erzwingen kann. Und aufgrund der Einschränkungen des Spring-Transaktionsframeworks können Benutzer kein Force-Commit explizit aufrufen. Ich kämpfe immer noch mit diesem Problem.

Es gibt zwei Lösungen:

  • Bei Verwendung von AOP können 4-Byte-UTF8-Zeichen eingefügt werden. Die Frontmethode führt dann set names utf8mb4 aus. Mit dieser Lösung lässt sich jedoch nicht bestimmen, ob die AOP-Methode von Spring-Transaktionen verwaltet wird und ob die in der Frontmethode erhaltene Verbindung dieselbe Sitzung ist wie das später erhaltene Verbindungsobjekt.
  • Studieren Sie die Erstellungsmethode von Spring JDBC und schreiben Sie einen Hook, um bei jeder Erstellung einer neuen Datenbankverbindung set names utf8mb4 auszuführen, sodass für jede Verbindung der festgelegte Zeichensatz garantiert ist.

Zusammenfassen

Das Obige ist der gesamte Inhalt dieses Artikels. Ich werde mit den beiden oben genannten Lösungen experimentieren, wenn ich Zeit habe. Ich hoffe, dass der Inhalt dieses Artikels Ihnen bei Ihrem Studium oder Ihrer Arbeit hilfreich sein kann. Wenn Sie Fragen haben, können Sie uns gerne eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • Detaillierte Schritte zum Speichern von Emoji-Ausdrücken in MySQL
  • Gründe und Lösungen für das fehlgeschlagene Einfügen von Emoji-Ausdrücken in MySQL
  • Analyse der Lösung für MySQLs Unfähigkeit, Emoji-Ausdrücke zu speichern
  • So gehen Sie mit Fehlern im Emoji-Tabellenspeicher von MySQL um [Kodierung auf utf8mb4 ändern]
  • Analyse von Lösungen für das Problem, dass MySQL keine Emoji-Ausdrücke speichern kann
  • So aktivieren Sie die Java-Backend-MySQL-Datenbank zur Unterstützung von Emoji-Ausdrücken
  • Tutorial zum Einrichten von MySQL zum Speichern von Emoji-Zeichen
  • So fügen Sie Emoji-Ausdrücke in MySQL ein

<<:  Packetdrills prägnantes Benutzerhandbuch

>>:  So konfigurieren Sie SSH/SFTP und legen Berechtigungen unter dem Linux-Betriebssystem fest

Artikel empfehlen

Webdesigner ist ein geeignetes Talent

<br />Es gibt keine Straße auf der Welt. Wen...

Reagiert auf verschiedene Arten, Parameter zu übergeben

Inhaltsverzeichnis Übergeben von Parametern zwisc...

Eine kurze Diskussion über die MySQL-Optimierungslösung für große Tabellen

Hintergrund Die Menge neuer Daten in der Geschäft...

jQuery-Plugin zum Erreichen eines Bildvergleichs

In diesem Artikelbeispiel wird der spezifische Co...

Klasse in Front-End-JavaScript

Inhaltsverzeichnis 1. Klasse 1.1 Konstruktor() 1....

HTML-Code zum Hinzufügen von Symbolen zum transparenten Eingabefeld

Ich habe vor Kurzem eine Website mit Anwaltsempfe...

So starten und starten Sie nginx unter Linux neu

Nginx (Engine x) ist ein leistungsstarker HTTP- u...

So zeigen Sie Bilder im TIF-Format im Browser an

Der Browser zeigt Bilder im TIF-Format an Code kop...

MYSQL Performance Analyzer EXPLAIN Anwendungsbeispielanalyse

Dieser Artikel veranschaulicht anhand eines Beisp...

JavaScript zum Anzeigen und Ausblenden des Dropdown-Menüs

In diesem Artikel wird der spezifische Code für J...

Detaillierte Erläuterung der Vue-Projektverpackung

Inhaltsverzeichnis 1. Zugehörige Konfiguration Fa...

So installieren Sie Nginx in Docker

Installieren Sie Nginx auf Docker Nginx ist ein l...