[JAVA] Comment utiliser la même classe Mapper dans plusieurs sources de données avec Spring Boot + MyBatis

introduction

Dans le cas où j'ai vécu Puisque nous avons construit un système utilisant différentes sources de données et la même définition de table, Nous partagerons le savoir-faire à ce moment-là.

Définition de la source de données

Le pilote utilise "Oracle", mais veuillez le modifier en fonction de votre environnement.

application.yml


spring:
  datasource:
    #Source de données A
    alpha:
      jdbc-url: jdbc:oracle:thin:@localhost:1521/XEPDB1
      username: sample_a
      password: sample_a
      driverClassName: oracle.jdbc.OracleDriver
    #Source de données B
    beta:
      jdbc-url: jdbc:oracle:thin:@localhost:1521/XEPDB1
      username: sample_b
      password: sample_b
      driverClassName: oracle.jdbc.OracleDriver

Paramètres MyBatis

DataSourceConfig.java


package com.example;

@Configuration
@MapperScan(basePackages = { "com.example.mapper" }, sqlSessionTemplateRef = "sqlSessionTemplate") // ①
public class DataSourceConfig {

    @Bean(name = "alphaDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.alpha")
    public DataSource alphaDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "betaDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.beta")
    public DataSource betaDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean("dynamicDataSource")
    public DynamicRoutingDataSourceResolver dynamicDataSource(@Qualifier("alphaDataSource") DataSource alphaDataSource, @Qualifier("betaDataSource") DataSource betaDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        targetDataSources.put(DataSourceType.ALPHA, alphaDataSource);
        targetDataSources.put(DataSourceType.BETA, betaDataSource);

        //Changement dynamique de source de données
        DynamicRoutingDataSourceResolver resolver = new DynamicRoutingDataSourceResolver();
        resolver.setTargetDataSources(targetDataSources);
        resolver.setDefaultTargetDataSource(alphaDataSource);

        return resolver;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DynamicRoutingDataSourceResolver resolver) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

        // ②
        factoryBean.setDataSource(resolver);
        factoryBean.setMapperLocations("Chemin XML du mappeur");
        factoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);

        return factoryBean.getObject();
    }

    // ...réduction
}

①: Définissez un alias pour la classe Mapper couramment utilisée (2): la configuration automatique est désactivée pour les sources multi-données, donc définissez-la manuellement.

Changement de source de données

Définissez une valeur de partition pour déterminer la source de données de référence.

public enum DataSourceType {
    ALPHA, BETA
}

La valeur de division est conservée pour chaque thread.

DataSourceContextHolder.java


public class DataSourceContextHolder {

    private static ThreadLocal<DataSourceType> contextHolder = new ThreadLocal<DataSourceType>();

    public static void setDataSourceType(DataSourceType dataSourceType) {
        contextHolder.set(dataSourceType);
    }

    public static DataSourceType getDataSourceType() {
        return contextHolder.get();
    }

    public static void clear() {
        contextHolder.remove();
    }
}

Acquérir la valeur de classification pour déterminer la source de données de référence. À partir de l'ensemble de sources de données dans DataSourceConfig.dynamicDataSource avec cette valeur d'indicateur Déterminez la source de données à laquelle se référer réellement.

DynamicRoutingDataSourceResolver.java


public class DynamicRoutingDataSourceResolver extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSourceType();
    }
}

comment utiliser

Définissons le DataSourceType via le DataSourceContextHolder. Si vous souhaitez le définir comme un processus transversal, utilisez AOP, etc. pour changer de source de données.

DataSourceContextHolder.setDataSourceType(DataSourceType.ALPHA);

Recommended Posts

Comment utiliser la même classe Mapper dans plusieurs sources de données avec Spring Boot + MyBatis
Comment utiliser MyBatis2 (iBatis) avec Spring Boot 1.4 (Spring 4)
Comment utiliser h2db intégré avec Spring Boot
Comment utiliser CommandLineRunner dans Spring Batch of Spring Boot
Comment appeler et utiliser l'API en Java (Spring Boot)
Comment utiliser le type d'énumération Java (Enum) dans Mapper XML de MyBatis
Mappage à une classe avec un objet de valeur dans How to My Batis
Comment utiliser Lombok au printemps
Remarques sur l'utilisation de Spring Data JDBC
Comment utiliser la classe wrapper
Comment utiliser l'annotation MyBatis Mapper
Comment utiliser ModelMapper (Spring boot)
Comment utiliser MinIO avec la même fonction que S3 Utiliser docker-compose
Comment appeler plusieurs noms à la fois dans la même catégorie
[Java] Comment utiliser la classe File
[Traitement × Java] Comment utiliser la classe
[Java] Comment utiliser la classe Calendar
Comment appliquer immédiatement les modifications de Thymeleaf au navigateur avec #Spring Boot + maven
Comment lire le corps de la requête plusieurs fois avec Spring Boot + Spring Security
Jusqu'à l'acquisition de données avec Spring Boot + MyBatis + PostgreSQL
Comment utiliser les attributs de session Spring Boot (@SessionAttributes)
Comment ajouter un chemin de classe dans Spring Boot
Comment se lier avec un fichier de propriétés dans Spring Boot
[JAVA] [Spring] [MyBatis] Utiliser IN () avec SQL Builder
Comment définir plusieurs orm.xml dans Spring4, JPA2.1
[Spring Boot] Comment se référer au fichier de propriétés
[Rails] Comment enregistrer plusieurs enregistrements dans la table intermédiaire avec une association plusieurs-à-plusieurs
Comment stocker des objets dans PostgreSQL au format JSON avec MyBatis (Mapper XML)
Comment effectuer UT avec Excel en tant que données de test avec Spring Boot + JUnit5 + DBUnit
Comment définir des variables d'environnement dans le fichier de propriétés de l'application Spring Boot
Comment changer l'action avec plusieurs boutons d'envoi
Comment utiliser la bibliothèque Z3 dans Scala avec Eclipse
Comment créer un projet Spring Boot dans IntelliJ
Organisé comment interagir avec le JDK par étapes
Comment utiliser la bibliothèque JDD dans Scala avec Eclipse
Comment démarrer par environnement avec Spring Boot de Maven
Comment utiliser le référentiel de jobs en mémoire avec Spring Batch
Comment utiliser git avec la puissance de jgit dans un environnement sans commandes git
Résumé de l'utilisation du jeu de proxy dans IE lors de la connexion avec Java
Comment utiliser la méthode getter / setter (en orientation objet)
Comment modifier la valeur de paramètre de application.properties au moment du démarrage dans Spring Boot
Utilisez collection_select pour extraire les données stockées dans Active_Hash
Comment utiliser les données JSON dans la communication WebSocket (Java, JavaScript)
Comment passer un objet à Mapper dans MyBatis sans passer par un argument
Comment écrire dans la classe Model lorsque vous souhaitez enregistrer des données binaires dans DB avec PlayFramework
Comment créer une partie d'espace réservé à utiliser dans la clause IN
Comment utiliser la classe Java
Mettez en majuscule uniquement la plage spécifiée avec la sous-chaîne. (Comment utiliser la sous-chaîne)
Flux jusqu'à la sortie des données de la table à afficher avec Spring Boot
Comment ajouter les mêmes index dans un tableau imbriqué
Utilisez thymeleaf3 avec le parent sans spécifier spring-boot-starter-parent dans Spring Boot
Utiliser Spring JDBC avec Spring Boot
gestion des erreurs wsimport (une classe / interface avec le même nom "xxx" est déjà utilisée)
Découvrons comment recevoir avec Request Body avec l'API REST de Spring Boot
Utilisez @ControllerAdvice, @ExceptionHandler, HandlerExceptionResolver dans Spring Boot pour intercepter les exceptions