Intégration de MyBatis-Plus dans Ruoyi-Vue

Ce guide détaille les étapes nécessaires pour intégrer MyBatis-Plus dans un projet backend Ruoyi-Vue.

  1. Ajout de MyBatis-Plus au POM principal

Il est mensionné dans certaines documentations d'ajouter également PageHelper. Cependant, le projet backend Ruoyi-Vue inclut déjà PageHelper, donc cette étape est omise.

Définissez les versions pour MyBatis-Plus et Lombok :


<mybatis-plus.version>3.5.2</mybatis-plus.version>
<lombok.version>1.18.12</lombok.version>

Ajoutez les dépendances au fichier POM prinicpal :


<!-- Dépendance MyBatis-Plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>

  1. Inclusion de MyBatis-Plus dans le POM de ruoyi-common

Ajoutez les dépendances suivantes au fichier POM du module ruoyi-common :


<!-- Dépendance MyBatis-Plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<!-- Lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

  1. Intégration de MyBatis-Plus dans le POM de ruoyi-framework

Ajoutez les dépendances suivantes au fichier POM du module ruoyi-framework :


<!-- MyBatis-Plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<!-- Lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

Dans le répertoire ruoyi-framework/src/main/java/com/ruoyi/framework/config, supprimez la classe MybatisConfig et créez la classe MybatisPlusConfig avec le contenu suivant :


package com.ruoyi.framework.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

@Configuration
public class MybatisPlusConfig {
    private static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
    @Autowired
    private Environment env;

    public static String setTypeAliasesPackage(String typeAliasesPackage) {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
        List<String> allResult = new ArrayList<>();
        try {
            for (String aliasesPackage : typeAliasesPackage.split(",")) {
                List<String> result = new ArrayList<>();
                aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                        + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
                Resource[] resources = resolver.getResources(aliasesPackage);
                if (resources != null && resources.length > 0) {
                    MetadataReader metadataReader;
                    for (Resource resource : resources) {
                        if (resource.isReadable()) {
                            metadataReader = metadataReaderFactory.getMetadataReader(resource);
                            try {
                                result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
                            } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                if (!result.isEmpty()) {
                    HashSet<String> hashResult = new HashSet<>(result);
                    allResult.addAll(hashResult);
                }
            }
            if (!allResult.isEmpty()) {
                typeAliasesPackage = String.join(",", allResult.toArray(new String[0]));
            } else {
                throw new RuntimeException("Error scanning mybatis typeAliasesPackage, parameter typeAliasesPackage: " + typeAliasesPackage + " found no packages");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return typeAliasesPackage;
    }

    public Resource[] resolveMapperLocations(String[] mapperLocations) {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList<>();
        if (mapperLocations != null) {
            for (String mapperLocation : mapperLocations) {
                try {
                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
                    resources.addAll(Arrays.asList(mappers));
                } catch (IOException e) {
                    // Ignore
                }
            }
        }
        return resources.toArray(new Resource[0]);
    }

    /**
     * Configuration for the new version
     * @return MybatisPlusInterceptor bean
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // Add various interceptors
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // Optimistic locker interceptor
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

Dans le répertoire ruoyi-framework/src/main/java/com/ruoyi/framework/, créez un package nommé mybatisplus et, à l'intérieur de ce package, créez la classe MyMetaObjectHandler :


package com.ruoyi.framework.mybatisplus;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.time.LocalDateTime;

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    private static final String CREATE_BY = "createBy";
    private static final String CREATE_TIME = "createTime";
    private static final String UPDATE_BY = "updateBy";
    private static final String UPDATE_TIME = "updateTime";
    private static final String DELETED = "delFlag";

    /**
     * Fill strategy for insert operations.
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // Recommended from version 3.3.0
        this.setFieldValByName(CREATE_BY, SecurityUtils.getUsername(), metaObject);
        this.setFieldValByName(CREATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);
        this.setFieldValByName(UPDATE_BY, SecurityUtils.getUsername(), metaObject);
        this.setFieldValByName(UPDATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);
        this.setFieldValByName(DELETED, "0", metaObject);
    }

    /**
     * Fill strategy for update operations.
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName(UPDATE_BY, SecurityUtils.getUsername(), metaObject);
        this.setFieldValByName(UPDATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);
    }

    /**
     * Handles specific date types.
     * @param setterType The type of the setter argument.
     * @return The formatted date object.
     */
    private Object formatDate(Class<?> setterType) {
        if (Date.class.equals(setterType)) {
            return new Date();
        } else if (LocalDateTime.class.equals(setterType)) {
            return LocalDateTime.now();
        } else if (Long.class.equals(setterType)) {
            return System.currentTimeMillis();
        }
        return null;
    }
}

  1. Configuration de MyBatis-Plus dans application.yml du projet ruoyi-admin

Dans le fichier application.yml du projet ruoyi-admin, assurez-vous de commenter la configuration Mybatis existante et d'ajouter la configuration pour MyBatis-Plus comme suit :


# MyBatis Configuration (Commented out)
#mybatis:
#  # Alias package for types
#  typeAliasesPackage: com.ruoyi.**.domain
#  # Mapper XML file location
#  mapperLocations: classpath*:mapper/**/*Mapper.xml
#  # Global configuration file location
#  configLocation: classpath:mybatis/mybatis-config.xml

# MyBatis-Plus Configuration
mybatis-plus:
  # Location of corresponding XML files
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # Entity scanning, separate multiple packages with commas or semicolons
  typeAliasesPackage: com.ruoyi.**.domain
  # Optional: Base type for entity scanning
  #typeAliasesSuperType: Class>
  # Optional: Type handlers package
  #typeHandlersPackage: null
  # Optional: Enum types package for entity fields
  #typeEnumsPackage: null
  # Check if MyBatis XML files exist on startup, default is false
  checkConfigLocation: false
  # MyBatis executor type: SIMPLE, REUSE, BATCH
  executorType: SIMPLE
  # External configuration properties for MyBatis
  configurationProperties: null
  configuration:
    # Enable automatic camel case to underscore mapping
    mapUnderscoreToCamelCase: true
    # Default enum type handler. Options: org.apache.ibatis.type.EnumTypeHandler (stores name), org.apache.ibatis.type.EnumOrdinalTypeHandler (stores ordinal), com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler (requires IEnum or @EnumValue)
    defaultEnumTypeHandler: org.apache.ibatis.type.EnumTypeHandler
    # Enable aggressive lazy loading
    aggressiveLazyLoading: true
    # MyBatis automatic mapping behavior: NONE, PARTIAL, FULL
    autoMappingBehavior: PARTIAL
    # Handling of unknown columns or properties during automatic mapping: NONE, WARNING, FAILING
    autoMappingUnknownColumnBehavior: NONE
    # MyBatis level 1 cache scope: SESSION or STATEMENT
    localCacheScope: SESSION
    # Enable MyBatis level 2 cache, default is true
    cacheEnabled: true
  global-config:
    # Whether to display the logo banner on startup
    banner: true
    # Whether to initialize SqlRunner
    enableSqlRunner: false
    dbConfig:
      # ID type: AUTO (auto-increment), NONE (none), INPUT (user input), ASSIGN_ID (global unique ID), ASSIGN_UUID (global unique UUID)
      idType: AUTO
      # Table name prefix
      tablePrefix: null
      # Column naming format, e.g., '%s'. Not applicable to primary keys.
      columnFormat: null
      # Whether to use snake_case for table names (converts camelCase)
      tableUnderline: true
      # Use uppercase for table and column names
      capitalMode: false
      # Global logic delete field name
      logicDeleteField: null
      # Value for logically deleted records
      logicDeleteValue: 2
      # Value for logically undeleted records
      logicNotDeleteValue: 0
      # Field strategy for insert operations: IGNORED, NOT_NULL, NOT_EMPTY, DEFAULT, NEVER
      insertStrategy: NOT_NULL
      # Field strategy for update operations: IGNORED, NOT_NULL, NOT_EMPTY, DEFAULT, NEVER
      updateStrategy: NOT_NULL
      # Field strategy for select operations (wrapper conditions): IGNORED, NOT_NULL, NOT_EMPTY, DEFAULT, NEVER
      selectStrategy: NOT_NULL

Étiquettes: MyBatis-Plus ruoyi spring-boot Java JPA

Publié le 19 juillet à 13h23