IDEA項目搭建九——MybatisPlus多數據庫實現


一、簡介

MybatisPlus中引用多數據庫時,傳統的配置就失效了,需要單獨寫配置來實現,下面就說一下具體應該如何操作

二、引入MybatisPlus多數據源配置

還是先看一下我的項目結構,Model是單獨的模塊,請自行創建

 1、創建一個Maven項目,修改pom.xml文件增加對spring boot、mybatis plus、druid、mysql connector的引用 

    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>        
        <!--import druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--import mysql connector-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>
        <!--import mybatis plus 它會自動引入mybatis及mybatis spring切勿重復引用以免沖突-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>2.3</version>
        </dependency>
    </dependencies>

  2、創建resources文件夾,並創建application.yml文件增加以下配置,此處不需要寫mybatis plus的配置了,因為多數據源時這里的mybatis plus會失效,具體原因還沒找到

#設置提供的服務名
spring:
  application:
    name: javademo-tyh-service-hotel
  #配置數據庫
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    db1:
      url: jdbc:mysql://10.11.12.237:3306/db_test?useUnicode=true&characterEncoding=utf8
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver
    db2:
      url: jdbc:mysql://10.11.12.237:3306/tyh_test?useUnicode=true&characterEncoding=utf8
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver

#設置自己啟動的端口
server:
  port: 12000

  3、在resources文件夾下創建mapper文件夾,在其內部創建兩個數據庫的兩張表的mapper.xml文件,分別編寫一個自定義方法

BaseInfoMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 指明當前xml對應的Mapper -->
<mapper namespace="javademo.tyh.service.hotel.mapper.BaseInfoMapper">
    <select id="listCount" resultType="Integer">
      select count(*) from base_info;
    </select>
</mapper>

 UserInfoMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 指明當前xml對應的Mapper -->
<mapper namespace="javademo.tyh.service.hotel.mapper.UserInfoMapper">
    <select id="listCount" resultType="Integer">
      select count(*) from user_info;
    </select>
</mapper>

 4、打開main方法所在的類並修改為如下代碼

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("javademo.tyh.service.hotel.mapper")//標記掃描的mapper位置
public class AppServiceHotel
{
    public static void main( String[] args )
    {
        SpringApplication.run(AppServiceHotel.class, args);
    }
}

 5、創建config文件夾,存放mybatis plus的相關配置,此內部的類很多都摘自官網,是按照他的方式進行實現的

創建枚舉DBTypeEnum

/**
 * 多數據源枚舉
 */
public enum DBTypeEnum {
    db1("db1"), db2("db2");
    private String value;
    DBTypeEnum(String value) {
        this.value = value;
    }
    public String getValue() {
        return value;
    }
}

 創建數據源操作類DbContextHolder

public class DbContextHolder {
    private static final ThreadLocal contextHolder = new ThreadLocal<>();
    /**
     * 設置數據源
     * @param dbTypeEnum
     */
    public static void setDbType(DBTypeEnum dbTypeEnum) {
        contextHolder.set(dbTypeEnum.getValue());
    }
    /**
     * 取得當前數據源
     * @return
     */
    public static String getDbType() {
        return (String) contextHolder.get();
    }
    /**
     * 清除上下文數據
     */
    public static void clearDbType() {
        contextHolder.remove();
    }
}

 創建spring的DataSource抽象類 DynamicDataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/*
* 擴展Spring的AbstractRoutingDataSource抽象類,實現動態數據源。
* AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是實現數據源的route的核心,
* 這里對該方法進行Override。 【上下文DbContextHolder為一線程安全的ThreadLocal】
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
    /**
     * 取得當前使用哪個數據源
     * @return
     */
    @Override
    protected Object determineCurrentLookupKey(){
        return DbContextHolder.getDbType();
    }
}

 創建MybatisPlusConfig配置類

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * MybatisPlus配置
 */
@Configuration
public class MybatisPlusConfig {
    // 分頁攔截器
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    //定義db1
    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")//與配置文件中的層次結構相同
    public DataSource db1() {
        return DruidDataSourceBuilder.create().build();
    }
    //定義db2
    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")//與配置文件中的層次結構相同
    public DataSource db2() {
        return DruidDataSourceBuilder.create().build();
    }
     /**
     * 動態數據源配置
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DBTypeEnum.db1.getValue(), db1);
        targetDataSources.put(DBTypeEnum.db2.getValue(), db2);
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(db1);
        return dynamicDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        //***導入MybatisSqlSession配置***
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        //指明數據源
        sqlSessionFactory.setDataSource(multipleDataSource(db1(), db2()));
        //指明mapper.xml位置(配置文件中指明的xml位置會失效用此方式代替,具體原因未知)
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/**Mapper.xml"));
        //指明實體掃描(多個package用逗號或者分號分隔)
        sqlSessionFactory.setTypeAliasesPackage("javademo.tyh.model.base;javademo.tyh.model.hotel");

        //***導入Mybatis配置***
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{paginationInterceptor()});

        //***導入全局配置***
        sqlSessionFactory.setGlobalConfig(globalConfiguration());
        return sqlSessionFactory.getObject();
    }

    /**
     * 在代碼中配置MybatisPlus替換掉application.yml中的配置
     * @return
     */
    @Bean
    public GlobalConfiguration globalConfiguration() {
        GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
        //主鍵類型 0:數據庫ID自增, 1:用戶輸入ID,2:全局唯一ID (數字類型唯一ID), 3:全局唯一ID UUID
        conf.setIdType(0);
        //字段策略(拼接sql時用於判斷屬性值是否拼接) 0:忽略判斷,1:非NULL判斷,2:非空判斷
        conf.setFieldStrategy(2);
        //駝峰下划線轉換含查詢column及返回column(column下划線命名create_time,返回java實體是駝峰命名createTime,開啟后自動轉換否則保留原樣)
        conf.setDbColumnUnderline(true);
        //是否動態刷新mapper
        conf.setRefresh(true);
        return conf;
    }
}

 6、創建mapper文件夾用於存放於xml對應的mapper接口

BaseInfoMapper

import com.baomidou.mybatisplus.mapper.BaseMapper;
import javademo.tyh.model.hotel.BaseInfoModel;
import org.springframework.stereotype.Component;

@Component
public interface BaseInfoMapper extends BaseMapper<BaseInfoModel> {
    //自定義方法
    int listCount();
}

 UserInfoMapper

import com.baomidou.mybatisplus.mapper.BaseMapper;
import javademo.tyh.model.hotel.UserInfoModel;
import org.springframework.stereotype.Component;

@Component
public interface UserInfoMapper extends BaseMapper<UserInfoModel> {
    //自定義方法
    int listCount();
}

 7、創建service文件夾用於存放業務邏輯類

import javademo.tyh.model.hotel.BaseInfoModel;
import javademo.tyh.model.hotel.UserInfoModel;
import javademo.tyh.service.hotel.config.DBTypeEnum;
import javademo.tyh.service.hotel.config.DbContextHolder;
import javademo.tyh.service.hotel.mapper.BaseInfoMapper;
import javademo.tyh.service.hotel.mapper.UserInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class HotelService {

    @Autowired
    BaseInfoMapper baseMapper;
    @Autowired
    UserInfoMapper userMapper;

    public void testDynamicDb() {
        //使用db1
        DbContextHolder.setDbType(DBTypeEnum.db1);
        BaseInfoModel baseModel = baseMapper.selectById(1);
        int baseCount = baseMapper.listCount();
        System.out.println("db1=" + baseModel.getNickname());
        //使用db2
        DbContextHolder.setDbType(DBTypeEnum.db2);
        UserInfoModel userModel = userMapper.selectById(1);
        int userCount = userMapper.listCount();
        System.out.println("db2=" + userModel.getUsername());
    }
}

 8、創建controller文件夾編寫一個controller和action用於測試

import javademo.tyh.service.hotel.service.HotelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/hotel")
public class HotelController {

    @Autowired
    HotelService service;

    @ResponseBody
    @RequestMapping("/test")
    public void test() {
        service.testDynamicDb();
    }
}

 9、創建自己的實體Model,get/set方法自己生成吧

BaseInfoModel

import com.baomidou.mybatisplus.annotations.TableName;
import java.time.LocalDateTime;

@TableName("base_info")
public class BaseInfoModel {
    private int id;
    private String nickname;
    private LocalDateTime updateTime;    
}

 UserInfoModel

import com.baomidou.mybatisplus.annotations.TableName;
import java.time.LocalDateTime;

@TableName("user_info")
public class UserInfoModel {
    private int id;
    private String username;
    private String password;
    private int sex;
    private int age;
    private LocalDateTime createTime;    
}

 OK,至此Mybatis Plus多數據源配置Demo就完成了,可以運行http://localhost:12000/hotel/test看一下console控制台會得到以下輸出,db1和db2就切換成功了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM