Mybatis+Druid多數據源配置


在日常開發中我們可能會用到多數據源開發,什么是多數據源?
簡單來講的話,就是一個項目連接多個數據庫。當然只是可能會用到,我暫時沒見過應用場景,但是還是了解學習一下
此項目可以基於上一個簡單集成項目進行簡單的修改,就能實現多數據源了。

application.yml配置

我們在上一個項目的基礎上進行修改,實現多數據源配置

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      one:
        username: root
        password: 123456
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
        initialSize: 5
        minIdle: 5
        maxActive: 20
        initial-size: 3
        min-idle: 3
        max-active: 10
        max-wait: 60000
      two:
        username: root
        password: 123456
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/layui?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
        initialSize: 5
        minIdle: 5
        maxActive: 20
        initial-size: 6
        min-idle: 6
        max-active: 20
        max-wait: 12000
      stat-view-servlet:
        login-username: admin
        login-password: admin
      filter:
        stat:
          log-slow-sql: true
          slow-sql-millis: 2000
mybatis:
  mapper-locations: classpath:mappers///Mapper.xml
  type-aliases-package: com.ccsert.spdruid..model
  configuration:
    map-underscore-to-camel-case: true

logging:
  file: logs/mass.log
  level:
    org.springframework: info
    com.ccsert: DEBUG

着是完整的配置
主要在druid數據源和mybatis的mapper.xml進行了細微修改
這里我建立一個layui數據庫,里面有個和demo里一樣的表,數據和結構都一樣,方便等會測試

包結構調整,代碼修改

包結構調整

我們先把mapper接口修改一下
在原來的mapper包下建立兩個包,一個one,一個two
然后把之前的mapper接口分別復制到one和two下
然后改一下名字
改完以后大概就是這個樣子

代碼修改

把之前的mapper注解都去掉
后面會用別的方法去映射
這是oneMapper

package com.ccsert.spdruid.test.mapper.one;

import com.ccsert.spdruid.test.model.TestUser;

import java.util.List;

public interface TestUserOneMapper {

    List<TestUser> getall();
    
    TestUser getById(Integer id);
    
    int save(TestUser testUser);

}

這是twoMapper

package com.ccsert.spdruid.test.mapper.two;

import com.ccsert.spdruid.test.model.TestUser;

public interface TestUserTwoMapper {
    TestUser getById(Integer id);
}

這里為了方便我就只寫一個接口
然后我們在修改一下service實現類

package com.ccsert.spdruid.test.service.impl;

import com.ccsert.spdruid.test.mapper.one.TestUserOneMapper;
import com.ccsert.spdruid.test.mapper.two.TestUserTwoMapper;
import com.ccsert.spdruid.test.model.TestUser;
import com.ccsert.spdruid.test.service.TestUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class TestUserServiceImpl implements TestUserService {
    @Resource
    private TestUserOneMapper testUserOneMapper;

    @Resource
    private TestUserTwoMapper testUserTwoMapper;
    @Override
    public List<TestUser> getall() {
        return testUserOneMapper.getall();
    }
    
    @Override
    public TestUser getById(Integer id) {
        return testUserTwoMapper.getById(id);
    }
    
    @Override
    public int save(TestUser testUser) {
        return testUserOneMapper.save(testUser);
    }

}

getById方法讓他去調用twoMapper
其余的還是讓它去調用原來的接口

配置文件修改

然后我們把xml的位置移動一下
在resources下的mappers下在建立兩個文件夾
一個one
一個two
然后在把之前的TestUser目錄復制兩份到one和two下
把原來的TestUser刪除掉
在把之前的xml名字修改一下
改完以后大概就是這個樣子了

onemapper.xml的內容保持不變
主要寫一下twomapper.xml的save保存方法

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ccsert.spdruid.test.mapper.two.TestUserTwoMapper" >
    <resultMap id="BaseResultMap" type="com.ccsert.spdruid.test.model.TestUser" >
        <id column="id" property="Id"  />
        <result column="user_name" property="userName"/>
        <result column="password" property="password" />
    </resultMap>

    <select id="getById" parameterType="Integer"  resultMap="BaseResultMap">
     SELECT
        id,user_name,password
    FROM
        test_user
    WHERE id=#{id}
    </select>

</mapper>





因為這里的mapper接口路徑是修改過的,onemapper.xml要注意一下
多數據源配置
准備工作做好了接着就是配置多數據源了
在test包下建立一個config包,用於存放配置
然后在config包下建立一個MultiDataSourceConfig類

package com.ccsert.spdruid.test.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
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 javax.sql.DataSource;

@Configuration
public class MultiDataSourceConfig {
    @Primary
    @Bean(name = "oneDataSource")
    @ConfigurationProperties("spring.datasource.druid.one")
    public DataSource dataSourceOne(){
        return DruidDataSourceBuilder.create().build();
    }
    @Bean(name = "twoDataSource")
    @ConfigurationProperties("spring.datasource.druid.two")
    public DataSource dataSourceTwo(){
        return DruidDataSourceBuilder.create().build();
    }
}

這里的ConfigurationProperties是獲取的yml或者properties里的值
spring.datasource.druid.one和spring.datasource.druid.two就是我們配置的數據源
Primary只能指定一個為默認數據源,這里指定了one數據庫
在config下建立DataSource1Config類,用於配置數據源one

package com.ccsert.spdruid.test.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.ccsert.spdruid.test.mapper.one", sqlSessionTemplateRef  = "test1SqlSessionTemplate")
public class DataSource1Config {

    @Bean(name = "test1SqlSessionFactory")
    @Primary
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/one/**/*Mapper.xml"));
        return bean.getObject();
    }
    
    @Bean(name = "test1TransactionManager")
    @Primary
    public DataSourceTransactionManager testTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean(name = "test1SqlSessionTemplate")
    @Primary
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

@MapperScan(basePackages = "com.ccsert.spdruid.test.mapper.one", sqlSessionTemplateRef = "test1SqlSessionTemplate")指定了實體類的路徑,這里就完成了映射,所以不需要在mapper接口上寫@Mapper注解

然后在建立一個DataSource2Config類

內容和上面的差不多

package com.ccsert.spdruid.test.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;


@Configuration
@MapperScan(basePackages = "com.ccsert.spdruid.test.mapper.two", sqlSessionTemplateRef  = "test2SqlSessionTemplate")
public class DataSource2Config {

    @Bean(name = "test2SqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/two/**/*Mapper.xml"));
        return bean.getObject();
    }

    @Bean(name = "test2TransactionManager")
    public DataSourceTransactionManager testTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "test2SqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

注意這兩個路徑寫成自己的不要搞錯了
到這里就配置完成了
測試使用
我們先訪問一下接口能否調通
啟動項目然后使用谷歌插件訪問接口

可以看到我們兩個接口都調用成功
我們去druid的監控界面查看一下執行的sql和數據源信息



可以看到druid監控了我們執行的兩條sql,以及兩個數據源信息


免責聲明!

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



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