Maison  >  Article  >  base de données  >  Solution au problème de l'échec de l'insertion d'expressions emoji dans MySQL

Solution au problème de l'échec de l'insertion d'expressions emoji dans MySQL

巴扎黑
巴扎黑original
2017-05-14 14:20:051745parcourir

Les expressions Emoji sont souvent rencontrées dans notre développement quotidien, mais j'ai récemment rencontré un problème lors de l'insertion d'expressions emoji dans MySQL. Je l'ai finalement résolu en recherchant des informations pertinentes, je partagerai donc principalement le processus de résolution de ce problème. Je vais vous présenter la solution au problème de l'échec de MySQL à insérer des expressions emoji. Les amis dans le besoin peuvent s'y référer.

Avant-propos

J'ai toujours pensé que UTF-8 était une solution universelle aux problèmes de jeux de caractères jusqu'à ce que je rencontre ce problème récemment. Récemment, je travaillais sur un robot d'exploration pour Sina Weibo. Lors de l'enregistrement, j'ai découvert que tant que je conservais l'expression emoji, l'exception suivante serait levée :


<.>
Incorrect string value: &#39;\xF0\x90\x8D\x83\xF0\x90...&#39;
Le célèbre UTF -8 fait 3 octets, ce qui inclut déjà la plupart des polices que nous voyons chaque jour. Mais 3 octets sont loin d'être suffisants pour contenir tout le texte, il existe donc utf8mb4, qui est un sur-ensemble d'utf8. , représentant 4 octets, rétrocompatible avec utf8. Les expressions emoji que nous utilisons quotidiennement font 4 octets


Donc ici, lorsque nous insérons des données dans la table de données utf8, elle signalera

cette erreur. .Incorrect string value

Il est facile de trouver la solution via Google. La solution spécifique est la suivante :


1. table Il est très simple de modifier utf8mb4

Vous pouvez trouver de nombreuses instructions de modification en ligne, mais il est recommandé de reconstruire la table, utilisez

pour sauvegarder. la table de données correspondante et modifiez la construction. Le jeu de caractères de l'instruction table est utf8mb4, puis mysqldump -uusername -ppassword database_name table_name > table.sql réimportez SQL pour terminer l'opération de modification du jeu de caractères mysql -uusername -ppassword database_name < table.sql

<.> 2. La version de la base de données MySQL doit être 5.5.3 et supérieure Ce qui précède
Tous les articles sur Internet indiquent que MySQL 5.5.3 ou supérieur est requis pour prendre en charge utf8mb4 Cependant, la version de la base de données que j'ai utilisée est la 5.5.18, et le problème peut toujours être résolu, les étudiants ne doivent donc pas se précipiter vers le frère d'exploitation et de maintenance pour mettre à niveau la base de données, essayez d'abord de voir si vous pouvez résoudre. résolvez le problème par vous-même.


3. Modifiez le fichier de configuration de la base de données /etc/my .cnf et redémarrez le service mysql
Principalement pour modifier le jeu de caractères par défaut de la base de données, ainsi que le jeu de caractères de connexion et de requête, [Mysql prend en charge les emoji et le codage de mise à niveau des émoticônes est UTF8MB4][ 1] Cet article contient des méthodes de configuration détaillées, [En profondeur Paramètres du jeu de caractères Mysql][2] Cet article présente le rôle de chaque jeu de caractères, vous pouvez en apprendre davantage.


4. Mettez à niveau le connecteur MySQL vers 5.1. 21 et supérieur
Pour toutes les opérations ci-dessus, la plus critique est l'étape 3, modifier le fichier de configuration de la base de données, qui concerne la modification



Ces configurations spécifient le jeu de caractères utilisé par les canaux que les données transmettent du client au serveur, où chaque canal apparaît. Des problèmes peuvent provoquer un échec d'insertion ou des caractères tronqués
[client]
# 客户端来源数据的默认字符集
default-character-set = utf8mb4
[mysqld]
# 服务端默认字符集
character-set-server=utf8mb4
# 连接层默认字符集
collation-server=utf8mb4_unicode_ci
[mysql]
# 数据库默认字符集
default-character-set = utf8mb4
.


Mais souvent, les bases de données en ligne ne peuvent pas modifier les fichiers de base de données avec désinvolture, donc nos camarades de classe d'exploitation et de maintenance m'ont catégoriquement refusé de modifier la configuration de la base de données (T_T)


Donc c'est possible. ne peut être résolu qu'avec du code. La première étape consiste à partir du jeu de caractères spécifié lors de la connexion à JDBC.



Changer principalement d'UTF-8 en utf8mb4. pour les chaînes Java Style Charset devraient résoudre le problème, n'est-ce pas ?
jdbc:mysql://localhost:3306/ding?characterEncoding=UTF-8


Mais malheureusement, Java JDBC n'a pas de jeu de caractères pour utf8mb4. Lors de l'utilisation d'UTF-8, il peut être compatible avec urf8mb4 et se convertir automatiquement. le jeu de caractères.


Par exemple, pour utiliser des jeux de caractères UTF-8 de 4 octets avec Connector/J, configurez le serveur MySQL avec Character_set_server=utf8mb4 et laissez CharacterEncoding en dehors de la connexion Connector/J. string. Connector/J détectera alors automatiquement le paramètre UTF-8 – [MySQL : Utilisation des jeux de caractères et d'Unicode] [3]


Plus tard, j'ai fait de la vulgarisation scientifique lors de chaque requête. peut spécifier explicitement le jeu de caractères à utiliser. Utilisez

pour spécifier que le jeu de caractères de ce lien est utf8mb4, mais ce paramètre est requis à chaque fois. La connexion deviendra invalide après avoir été libérée. 🎜>La solution actuelle consiste à appeler et exécuter explicitement

lorsque vous devez insérer utf8mb4, tel que : set names utf8mb4

set names utf8mb4

Il convient de noter que lorsque nous utilisons le framework ORM, pour des raisons d'optimisation des performances, le framework retardera la soumission à moins que la transaction ne se termine ou que l'utilisateur n'appelle activement la soumission forcée, et la personne responsable de l'exécution

ne prendra toujours pas effet.

jdbcTemplate.execute("set names utf8mb4");
jdbcTempalte.execute("...");
Ici, j'utilise myBatis, en prenant MessageDao comme exemple

set names utf8mb4


À ce stade, le problème est résolu...


Hé, ce serait génial si les choses pouvaient se passer aussi bien. Dans le projet, mybatis est une instance et est géré par Spring, ce qui signifie que je ne peux pas obtenir sqlSession. être effectué. Et en raison des limites du cadre de transaction Spring, il ne permet pas aux utilisateurs d'appeler explicitement la soumission forcée.
// MessageDao
public interface MessageDao {
 @Update("set names utf8mb4")
 public void setCharsetToUtf8mb4();
 @Insert("insert into tb_message ......")
 public void insert(Message msg);
}
// test code
SqlSession sqlSession = sqlSessioFactory.openSession();
messageDao = sqlSession.getMapper(MessageDao.class);
messageDao.setCharsetToUtf8mb4();
// 强制提交
sqlSession.commit();
messageDao.insert(message);


Il existe deux solutions :


  • En utilisant AOP, lorsqu'il est possible d'insérer des caractères UTF8 de 4 octets, la méthode du préfixe est exécutée set names utf8mb4, mais cette solution ne peut pas encore déterminer si la méthode AOP sera gérée par Spring pour la transaction gestion, et dans la méthode front-end, vérifiez si le lien obtenu est la même session que l'objet de connexion obtenu ensuite.

  • Étudiez la méthode de création de Spring JDBC et écrivez un hook pour en créer un nouveau à chaque fois Lors de la connexion à la base de données, exécutez set names utf8mb4 une fois, vous assurant ainsi que le jeu de caractères a été défini pour chaque lien obtenu

.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn