Table des matières
Préface
Pièges de la méthode Setter-Getter
Découverte de problèmes
Solution
Raison
Mybatis (version 3.4.6) analyse la méthode get-set pour obtenir le code source du nom de l'attribut :
Mybatis analyse la méthode get-set pour tester le nom de l'attribut
Problème avec l'annotation @Accessor(chain = true)
Problème trouvé
Reason
Maison Java JavaBase Apprenez à connaître les pièges de Lombok

Apprenez à connaître les pièges de Lombok

Oct 09, 2020 pm 05:00 PM
lombok

La rubrique

Tutoriel de base Java vous présente les pièges de Lombok, qui est simple à utiliser.

Apprenez à connaître les pièges de Lombok

Préface

Le plug-in Lombok a été introduit dans le projet l'année dernière, ce qui a vraiment libéré les mains et remplacé certaines tâches simples répétitives (Getter, Setter , toString, etc. Écriture de méthodes), cependant, au cours du processus d'utilisation, certains pièges ont également été découverts. Au début, je n'ai pas réalisé qu'il s'agissait d'un problème de Lombok. Plus tard, j'ai suivi le code source des autres composants correspondants et j'ai trouvé. que c'était un problème de Lombok !

Pièges de la méthode Setter-Getter

Découverte de problèmes

Nous utilisons principalement l'annotation de la méthode Setter-Getter de Lombok dans le projet, qui est l'annotation combinée @Data, mais dans Lors du processus d'insertion de données à l'aide de Mybatis, un problème est survenu. Le problème est décrit comme suit :

我们有个实体类:
@Data
public class NMetaVerify{
    private NMetaType nMetaType;
    private Long id;
    ....其他属性
}复制代码
Copier après la connexion

Lorsque nous avons utilisé Mybatis pour insérer des données, nous avons constaté que d'autres attributs pouvaient être insérés normalement, à l'exception du nMetaType. l'attribut était dans la base de données. A toujours été nul.

Solution

Lorsque je débogue le code du projet pour appeler la méthode insert SQL de Mybatis, je vois que l'attribut nMetaType de l'objet NMetaVerify a toujours des données, mais après avoir exécuté l'insertion, la base de données Le champ nMetaType est toujours nul. Au départ, je pensais que mon type d'énumération était mal écrit. Après avoir examiné d'autres champs qui ont également des types d'énumération, ils peuvent être insérés normalement dans la base de données, ce qui me rend encore plus confus. J'ai donc retracé le code source de Mybatis et découvert que Mybatis utilisait la réflexion pour obtenir l'attribut nMetaType, en utilisant la méthode getxxxx pour l'obtenir. Cependant, j'ai trouvé que la méthode get de nMetaType semblait être un peu différente de la méthode getxxxx requise. par Mybatis Idem. Problème trouvé !

Raison

La méthode get-set générée par Lombok pour les attributs avec la première lettre en minuscule et la deuxième lettre en majuscule est générée par Mybatis et idea ou la méthode get-set officiellement reconnue par Java. La différence :

#Lombok生成的Get-Set方法
@Data
public class NMetaVerify {
    private Long id;
    private NMetaType nMetaType;
    private Date createTime;
    
    public void lombokFound(){
        NMetaVerify nMetaVerify = new NMetaVerify();
        nMetaVerify.setNMetaType(NMetaType.TWO); //注意:nMetaType的set方法为setNMetaType,第一个n字母大写了,
        nMetaVerify.getNMetaType();                                  //getxxxx方法也是大写
    }
}复制代码
Copier après la connexion
rrree

Mybatis (version 3.4.6) analyse la méthode get-set pour obtenir le code source du nom de l'attribut :

#idea,Mybatis,Java官方默认的行为为:
public class NMetaVerify {
    private Long id;
    private NMetaType nMetaType;
    private Date createTime;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public NMetaType getnMetaType() {//注意:nMetaType属性的第一个字母小写
        return nMetaType;
    }

    public void setnMetaType(NMetaType nMetaType) {//注意:nMetaType属性的第一个字母小写
        this.nMetaType = nMetaType;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}复制代码
Copier après la connexion

Mybatis analyse la méthode get-set pour tester le nom de l'attribut

package org.apache.ibatis.reflection.property;

import java.util.Locale;

import org.apache.ibatis.reflection.ReflectionException;

/**
 * @author Clinton Begin
 */
public final class PropertyNamer {

        private PropertyNamer() {
            // Prevent Instantiation of Static Class
        }

        public static String methodToProperty(String name) {
            if (name.startsWith("is")) {//is开头的一般是bool类型,直接从第二个(索引)开始截取(简单粗暴)
                    name = name.substring(2);
            } else if (name.startsWith("get") || name.startsWith("set")) {//set-get的就从第三个(索引)开始截取
                    name = name.substring(3);
            } else {
                    throw new ReflectionException("Error parsing property name '" + name + "'.  Didn't start with 'is', 'get' or 'set'.");
            }
            //下面这个判断很重要,可以分成两句话开始解释,解释如下
            //第一句话:name.length()==1
            //                      对于属性只有一个字母的,例如private int x;
            //                      对应的get-set方法是getX();setX(int x);
            //第二句话:name.length() > 1 && !Character.isUpperCase(name.charAt(1)))
            //                      属性名字长度大于1,并且第二个(代码中的charAt(1),这个1是数组下标)字母是小写的
            //                      如果第二个char是大写的,那就直接返回name
            if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
                    name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);//让属性名第一个字母小写,然后加上后面的内容
            }

            return name;
        }

        public static boolean isProperty(String name) {
                return name.startsWith("get") || name.startsWith("set") || name.startsWith("is");
        }

        public static boolean isGetter(String name) {
                return name.startsWith("get") || name.startsWith("is");
        }

        public static boolean isSetter(String name) {
                return name.startsWith("set");
        }

}复制代码
Copier après la connexion

Solution

    @Test
    public void foundPropertyNamer() {
        String isName = "isName";
        String getName = "getName";
        String getnMetaType = "getnMetaType";
        String getNMetaType = "getNMetaType";

        Stream.of(isName,getName,getnMetaType,getNMetaType)
                .forEach(methodName->System.out.println("方法名字是:"+methodName+" 属性名字:"+ PropertyNamer.methodToProperty(methodName)));
    }
    
    #输出结果如下:
    方法名字是:isName 属性名字:name 
    方法名字是:getName 属性名字:name 
    方法名字是:getnMetaType 属性名字:nMetaType //这个以及下面的属性第二个字母都是大写,所以直接返回name
    方法名字是:getNMetaType 属性名字:NMetaType复制代码
Copier après la connexion

Problème avec l'annotation @Accessor(chain = true)

Problème trouvé

Exporter à l'aide d'easyexcel(github.com /alibaba/eas…) Lorsque j'ai vérifié, j'ai trouvé que les exportations de classes d'entités précédentes étaient toutes normales, mais maintenant la classe d'entités nouvellement ajoutée n'est pas normale. Après comparaison, il a été constaté que la classe d'entités nouvellement ajoutée ajoutait le @Accessor(. chain = true) annotation. Notre objectif principal est Il est pratique pour nous d'appeler la méthode set dans une chaîne :

1.修改属性名字,让第二个字母小写,或者说是规定所有的属性的前两个字母必须小写
2.如果数据库已经设计好,并且前后端接口对接好了,不想修改,那就专门为这种特殊的属性使用idea生成get-set方法复制代码
Copier après la connexion

Reason

La couche inférieure d'easyexcel utilise cglib comme boîte à outils de réflexion :

new UserDto()
.setUserName("")
.setAge(10)
........
.setBirthday(new Date());复制代码
Copier après la connexion

Mais cglib utilise la méthode rt A de Java de la classe Introspector dans .jar :

com.alibaba.excel.read.listener.ModelBuildEventListener 类的第130行
BeanMap.create(resultModel).putAll(map);

最底层的是cglib的BeanMap的这个方法调用

abstract public Object put(Object bean, Object key, Object value);复制代码
Copier après la connexion

Solution

# Introspector.java 第520行
if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) {
   pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null);
   //下面这行判断,只获取返回值是void类型的setxxxx方法
 } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) {
    // Simple setter
    pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method);
    if (throwsException(method, PropertyVetoException.class)) {
       pd.setConstrained(true);
    }
}复制代码
Copier après la connexion

Recommandations d'apprentissage gratuites associées : Tutoriel de base Java

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 de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Conseils professionnels : conseils d'experts et étapes pour installer avec succès le plug-in Eclipse Lombok Conseils professionnels : conseils d'experts et étapes pour installer avec succès le plug-in Eclipse Lombok Jan 28, 2024 am 09:15 AM

Conseils professionnels : conseils d'experts et étapes pour installer le plug-in Lombok dans Eclipse, des exemples de code spécifiques sont requis. Résumé : Lombok est une bibliothèque Java qui simplifie l'écriture de code Java grâce à des annotations et fournit des outils puissants. Cet article présentera aux lecteurs les étapes d'installation et de configuration du plug-in Lombok dans Eclipse et fournira des exemples de code spécifiques afin que les lecteurs puissent mieux comprendre et utiliser le plug-in Lombok. Téléchargez d'abord le plug-in Lombok, nous avons besoin

Tutoriel simple : installer rapidement le plug-in Lombok dans Eclipse Tutoriel simple : installer rapidement le plug-in Lombok dans Eclipse Jan 28, 2024 am 08:06 AM

Démarrage rapide : un didacticiel simple pour installer le plug-in Lombok dans Eclipse, qui nécessite des exemples de code spécifiques. Dans le processus de développement de projets Java, Lombok est souvent utilisé comme plug-in pratique. Lombok peut nous aider à simplifier le code Java, à réduire l'écriture de code passe-partout et à améliorer l'efficacité du développement. Cet article vous expliquera comment installer et configurer le plug-in Lombok dans Eclipse et fournira des exemples de code spécifiques. Étape 1 : Téléchargez le plug-in Lombok Tout d'abord, nous devons télécharger le plug-in Lombok depuis le site officiel de Lombok.

SpringBoot intègre Lombok et comment résoudre les problèmes courants SpringBoot intègre Lombok et comment résoudre les problèmes courants May 20, 2023 pm 12:46 PM

LombokLombok peut simplifier le code Java sous la forme d'annotations simples, améliorant ainsi l'efficacité du développement des développeurs. C'est une excellente bibliothèque de code Java en soi. Elle utilise un sucre syntaxique opportuniste pour simplifier le codage Java et fournit un moyen de rationaliser le code Java. Cependant, Lombok n'est pas une bibliothèque Java standard. Les classes Java qui doivent souvent être écrites pendant le développement Web nécessitent du temps pour ajouter les méthodes getter/setter, constructeur, égales et autres correspondantes. Lorsqu'il y a beaucoup d'attributs, il y aura un grand nombre de méthodes getter/setter. Celles-ci sont très longues et n'ont pas beaucoup de contenu technique. Une fois les attributs modifiés, il est facile d'oublier de modifier les méthodes correspondantes.

Guide complet d'installation du plugin Eclipse Lombok Guide complet d'installation du plugin Eclipse Lombok Jan 28, 2024 am 09:58 AM

Guide complet : Comment installer le plug-in Lombok pour Eclipse, exemple de code spécifique requis Introduction : Eclipse est un environnement de développement intégré (IDE) largement utilisé pour le développement Java. Lombok est une bibliothèque Java capable d'automatiser certains codes fastidieux pour améliorer l'efficacité du développement. Cet article détaille comment installer le plug-in Lombok dans Eclipse et fournit des exemples de code spécifiques. Étape 1 : Téléchargez le plug-in Lombok, ouvrez Eclipse et sélectionnez « Aide

Installation facile : conseils pour installer le plug-in Lombok dans Eclipse Installation facile : conseils pour installer le plug-in Lombok dans Eclipse Jan 28, 2024 am 09:29 AM

Conseils pratiques : Comment installer facilement le plug-in Lombok dans Eclipse, des exemples de code spécifiques sont nécessaires. Dans le développement Java quotidien, nous utilisons souvent Eclipse comme principal environnement de développement intégré. Dans le développement réel, nous pouvons rencontrer des opérations fastidieuses, telles que l'écriture manuelle des méthodes Getter et Setter. Pour simplifier ces opérations, nous pouvons utiliser le plug-in Lombok pour nous aider à générer automatiquement ces codes. Voici comment l'installer et le configurer facilement dans Eclipse

Comment utiliser la bibliothèque Java Lombok et les annotations Comment utiliser la bibliothèque Java Lombok et les annotations Jun 03, 2023 pm 09:28 PM

Qu'est-ce que Lombok ? Lombok est une bibliothèque Java conçue pour réduire les efforts de développement de code. Il fournit quelques annotations simples pour éliminer le code de modèle volumineux en Java, telles que les méthodes setter/getter les plus courantes dans pojo, telles que la méthode toString, la méthode égale, etc. Cela peut également nous aider à fermer le flux, même si JDK7 existe déjà. TWR est présent dans , mais ce package vaut le détour. Grâce à quelques annotations simples, le code du modèle est écrit dans le programme lors de la compilation. Vous pouvez voir la méthode générée dans la fenêtre Outline à l'aide d'Eclipse, mais elle est propre dans le code source. Pour l'installation, accédez d'abord au site officiel de Lombok pour télécharger le package jar. Téléchargez simplement le package jar

Utiliser Lombok pour simplifier le codage dans le développement d'API Java Utiliser Lombok pour simplifier le codage dans le développement d'API Java Jun 18, 2023 pm 11:34 PM

Java est un langage de programmation couramment utilisé pour développer divers types d'applications. L'API Java est l'un des éléments essentiels du langage Java. Elle fournit aux développeurs de nombreux codes et bibliothèques réutilisables qui peuvent accélérer le processus de développement et de déploiement d'applications. Au cours du processus de développement de l'API Java, il est souvent nécessaire d'utiliser certains outils et techniques pour simplifier le codage afin d'améliorer la lisibilité et la maintenabilité du code. Lombok est une bibliothèque Java très pratique et utilisable en Java

Quelles annotations existe-t-il pour Lombok en Java ? Quelles annotations existe-t-il pour Lombok en Java ? Apr 30, 2023 pm 03:52 PM

Exemples d'annotation 1. @ToString : implémente la méthode toString() 2. @Data : annoté sur la classe ; fournit des méthodes d'obtention et de définition pour tous les attributs de la classe. De plus, les méthodes equals, canEqual, hashCode et toString sont fournies 3. @Setter : annotation sur les propriétés ; fournit des méthodes de définition des propriétés. @Getter : Annoté sur l'attribut ; fournit une méthode d'obtention pour l'attribut @Log4j : Annoté sur la classe ; fournit un objet de journal log4j avec un attribut nommé log pour la classe @NoArgsConstructor : Annoté sur la classe ; la classe @Tous

See all articles