[JAVA] J'étais accro à la mise à jour de la déclaration dans MyBatis

introduction

L'auteur est toujours un ingénieur débutant qui a rejoint l'entreprise en 2018.

Donc le niveau de l'article n'est pas très élevé,

Je veux laisser les points auxquels j'étais accro lors de l'écriture de code en entreprise pour les futurs juniors! !!

→ Si vous voulez quand même le laisser, je veux l'écrire en Qiita! !! J'ai pensé et posté.

Contexte auquel j'étais accro cette fois

C'est l'histoire quand je faisais du développement backend avec Spring + MyBatis.

N objets envoyés à partir de la requête par la fonction en charge,

Après avoir traversé la logique, j'ai utilisé MyBatis pour mettre à jour plusieurs éléments.

Avant cela, qu'est-ce que My Batis?

Avant de parler de cette fois, parlons légèrement de My Batis.

MyBatis est un framework de mappage OR qui décrit SQL en XML.

Même si le développeur ne prend pas la peine d'écrire du SQL dans le mappeur OR Certains sont garantis un traitement CRUD normal,

MyBatis ose faire des jointures compliquées par écriture SQL, Vous pouvez mapper des SQL spéciaux tels que des instructions UPSERT à des objets Java, Les instructions If, foreach, etc. peuvent être écrites dans la partie SQL et du SQL dynamique peut être généré.
Exemple) L'instruction INSERT peut être écrite comme suit.

Fichier Java


public interface UserRepository{
	public int insertUser(List<User> userList);
}

Fichier XML


<insert id="insertUser" parameterType="java.util.List">
   INSERT INTO users( 
   		  user_id
   		, user_name
   		, user_mail
   )
   VALUES
   <foreach item="user" collection="list" open="" separator="," close="">
     (
          #{userId, jdbcType=BIGINT}
        , #{userName, jdbcType=VARCHAR}
        , #{userEmail, jdbcType=VARCHAR}
     )
   </foreach>
 </insert>

Dans le cas ci-dessus, remplissez l'objet Utilisateur avec la valeur que vous souhaitez enregistrer, En les transformant en liste et en les transmettant au mappeur OR, plusieurs INSERTs peuvent être effectués avec une émission de requête. Cette émission unique est bonne et vous pouvez réduire le nombre d'accès à la base de données sans dégrader les performances.

Accro à la mise à jour

Tournons Update en boucle avec la colle ci-dessus! J'en suis accro.

un événement

Plus précisément, lorsque le SQL suivant est écrit. (Java est omis)

Fichier XML


<update id ="updateUser" parameterType= "java.util.List" >
     <foreach collection ="itemList" item="item" separator= ";">
          update users
           <set>
                user_name = #{userName, jdbcType=VARCHAR}
              , user_email = #{userEmail, jdbcType=VARCHAR}
           </set >
          WHERE user_id = #{userId, jdbcType=VARCHAR}
     </foreach>
</update >

Par exemple, supposons que vous souhaitiez mettre à jour "Ah" et "Ii" avec le SQL ci-dessus. La requête émise par ceci est la suivante.

SQL émis


update users
  set
    user_name = 'Ah ah',
    user_email = '[email protected]'
where user_id = '001';
update users
  set
    user_name = 'Bien',
    user_email = '[email protected]'
where user_id = '002';

À première vue, cela a l'air bien, mais lorsque vous essayez de le traiter, une erreur se produit. Cependant, si ce SQL émis est envoyé directement à la table, le processus se terminera normalement.

Cause

Cela a du sens en termes de Mybatis, ou de méthodes Java (du moins pour moi).

En tant que comportement de Java, j'appellerai une méthode appelée updateUser. Parmi elles, n requêtes sont émises pour accéder à la base de données.
À ce stade, le nombre d'observations traitées par une émission de requête est renvoyé en tant que valeur de retour à la classe appelante. Dans le cas de l'instruction Update ci-dessus, plusieurs requêtes sont émises avec un seul appel de méthode, donc Une erreur se produit si vous essayez de renvoyer plusieurs valeurs de retour.

Pourquoi insérer peut foreach

Comme je l'ai écrit dans la section où j'ai parlé de My Batis, dans le cas de l'instruction Insert ** Parce que plusieurs processus sont exécutés en émettant une seule requête ** Même si vous enregistrez deux cas avec un seul appel de méthode Seule la valeur de retour est "2" et le nombre de valeurs de retour est de un, de sorte que le processus se termine normalement.

Comment boucler avec Update

Si la base de données peut utiliser des instructions UPSERT telles que mySQL, décrivez DUPLICATE KEY et écrivez-la. Il peut être résolu en utilisant UPSERT.

Exemple de traitement UPSERT


<insert id="upsertUser" parameterType="java.util.List">
    INSERT INTO users ( 
          user_id
        , user_name
        , user_mail
   )
   VALUES
   <foreach item="user" collection="list" open="" separator="," close="">
     (
        #{userId, jdbcType=BIGINT},
        #{userName, jdbcType=VARCHAR},
        #{userEmail, jdbcType=VARCHAR},
     )
   </foreach>
   ON DUPLICATE KEY UPDATE
     user_name = VALUES(userName),
     user_email = VALUES(userEmail)
 </insert>

Avec le SQL ci-dessus, une instruction INSERT sera émise une fois même à partir de l'objet à mettre à jour. Pour les instructions INSERT qui entraîneraient une violation de contrat unique au moment de l'exécution Le processus passe à l'instruction Update décrite dans ON DUPLICATE KEY UPDATE. Par conséquent, si n objets de mise à jour sont passés à ce processus, ** En conséquence, plusieurs mises à jour peuvent être effectuées en émettant une seule requête **, et le processus est effectué normalement.

en conclusion

Merci d'avoir lu jusqu'au bout. Si vous trouvez quelque chose d'étrange, veuillez le signaler. De plus, je continuerai à publier des articles, donc tout conseil d'écriture est le bienvenu!

Recommended Posts

J'étais accro à la mise à jour de la déclaration dans MyBatis
J'étais accro à la méthode du rouleau
J'étais accro au test Spring-Batch
J'étais accro à l'utilisation de RXTX avec Sierra
J'étais accro à NoSuchMethodError dans Cloud Endpoints
J'étais accro au record du modèle associé
J'étais accro au démarrage de sbt
Ce à quoi j'étais accro en utilisant rspec sur des rails
J'étais accro au réglage de laradock + VSCode + xdebug
Ce à quoi j'étais accro avec l'API REST Redmine
Une histoire à laquelle j'étais accro lors de l'obtention d'une clé qui a été automatiquement essayée sur MyBatis
L'histoire à laquelle j'étais accro lors de la création de STS
Une note quand j'étais accro à la conversion d'Ubuntu sur WSL1 en WSL2
À propos de la question pour laquelle j'étais accro à l'utilisation de hashmap
J'étais accro au paramètre API version min23 de registerTorchCallback
J'étais accro à la réécriture sur @ SpringApplicationConfiguration-> @SpringBootTest
Mémorandum: Ce à quoi j'étais accro quand j'ai frappé l'API de comptabilité freee
Une histoire à laquelle j'étais accro lors du test de l'API à l'aide de MockMVC
Enregistré parce que j'étais accro à l'entrée standard de la classe Scanner
J'étais accro au scrollview car je ne pouvais pas appuyer sur la taille variable UIView
[Circle CI] J'étais accro au test automatique de Circle CI (rails + mysql) [Memo]
J'étais accro aux tests unitaires avec l'opérateur de tampon dans RxJava
Une histoire à laquelle j'étais accro à deux reprises avec le paramètre de démarrage automatique de Tomcat 8 sur CentOS 8
J'étais accro à faire onActivityResult () avec DialogFragment
J'étais accro à ne pas pouvoir me connecter à AWS-S3 à partir du conteneur Docker
J'étais un peu accro à la comparaison S3 Checksum, alors prenez note.
Choses que j'ai tendance à oublier dans My Batis Résumé personnel
Je souhaite simplifier la sortie du journal sur Android
Le fichier CSV que j'ai pu télécharger a soudainement commencé à apparaître sur la page.
La partie à laquelle j'étais accro dans "Introduction à Ajax dans les applications Web Java" de NetBeans
Notez que j'étais accro aux paramètres du projet Android d'IntelliJ IDEA
Ce que j'ai corrigé lors de la mise à jour vers Spring Boot 1.5.12 ・ Ce à quoi j'étais accro
J'étais accro à la configuration de default_url_options avec l'introduction de la conception de Rails
Je veux mettre le JDK sur mon PC Mac
J'étais étrangement accro à l'utilisation de l'API Stream de Java avec Scala
Je souhaite simplifier l'instruction if-else de la branche conditionnelle en Java
Causes techniques et contre-mesures pour les points auxquels j'étais accro avec la première application Android et Kotlin
[Circle CI] Une histoire à laquelle j'étais accro chez Start Building
J'ai essayé de résumer ce qui était demandé lors de l'édition site-java-
Conférence spéciale sur la simulation multi-échelles: j'ai essayé de résumer le 5e
Ce à quoi j'étais accro lors de la mise en œuvre de l'authentification Google avec des rails
Conférence spéciale sur la simulation multi-échelles: j'ai essayé de résumer le 8
Je veux ajouter l'option désactivée à f.radio_button en fonction de la condition
J'ai essayé d'afficher le calendrier sur la console Eclipse en utilisant Java.
Conférence spéciale sur la simulation multi-échelles: j'ai essayé de résumer le 7
J'ai pu déployer l'application Docker + laravel + MySQL sur Heroku!
J'ai essayé d'expliquer la méthode
L'histoire que je voulais développer Zip
Mémo Android - J'étais accro à la permission
En vérifiant le fonctionnement de Java sous Linux, j'ai pu comprendre la compilation et la hiérarchie.
J'étais accro à l'idée de toucher MySQL 8.0 avec un sentiment de 5.7. Problème de configuration My.cnf
J'étais accro à un simple test de Jedis (bibliothèque Java-> Redis)
[Administrateur actif] Je souhaite personnaliser le traitement de création et de mise à jour par défaut
C'était une vie que je voulais réinitialiser le compteur associatif thread-safe