Spring Boot + MyBatis + Pagehelper 配置多數據源

 

前言:java

本文爲springboot結合mybatis配置多數據源,在項目當中不少狀況是使用主從數據源來讀寫分離,還有就是操做多庫,本文介紹如何一個項目同時使用2個數據源。mysql

也但願你們帶着思考去學習!博主是最近才學的配置寫成博文分享心得和技巧,文中有不足的歡迎留言指正,謝謝!git

思考:github

  一、若是從傳統的單數據源轉換爲多數據源,之前使用boot只用導包寫配置文件boot會幫咱們自動配置,若是不用自動配置咱們改怎麼配呢?web

  二、怎麼結合mybatis分頁插件一塊兒使用呢?spring

  .................sql

  

項目目錄結構數據庫

 

對主從數據庫分區,不一樣的數據源在不一樣的文件下易區分apache

      

建立2個數據庫  springboot

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `userName` varchar(32) DEFAULT NULL COMMENT '用戶名',
  `passWord` varchar(32) DEFAULT NULL COMMENT '密碼',
  `user_sex` varchar(32) DEFAULT NULL,
  `nick_name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;

INSERT INTO `users` VALUES ('28', 'asd', 'asda', '1', 'asd');

 

  使用一個表結構建立2個數據源  test一、test2

   

重要部分pom

<!-- mysql包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 用於springboot熱部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 阿里alibaba數據源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.6</version>
        </dependency>
        <!-- 添加JDBC依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- 分頁插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.3</version>
        </dependency>

pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>top.cmnbgy</groupId>
    <artifactId>spring-boot-ibatis-mulidatasource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>spring-boot-ibatis-mulidatasource</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.17.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- mysql包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 用於springboot熱部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 阿里alibaba數據源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.6</version>
        </dependency>
        <!-- 添加JDBC依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- 分頁插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

 

 

建立application.yml 文件

# 指定項目端口
server:
  port: 8080

spring:
  datasource:
  #主數據源 master: driverClassName : com.mysql.jdbc.Driver url : jdbc:mysql:
//localhost:3306/test1?useUnicode=true&characterEncoding=utf-8 username : root password : 1234
 
  #從數據源 slave: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8 username: root password: 1234 #配置分頁插件 pagehelper: helperDialect: mysql # 設置數據庫類型 reasonable: true #開啓合理化:頁碼<=0 查詢第一頁,頁碼>=總頁數查詢最後一頁 supportMethodsArguments: true #支持經過 Mapper 接口參數來傳遞分頁參數 params: count=countSql # 參數 成員變量 = ${ xx}

 使用spring boot官方推薦的yml文件配置,結構更清晰!

 

建立主數據源配置類   MasterDataSource  

  

 

package top.cmnbgy.springbootibatismulidatasource.dataSource;

import com.alibaba.druid.pool.DruidDataSource;
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.beans.factory.annotation.Value;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * 主數據源配置
 * @ClassName MasterDataSource
 * @Cescription TODO
 * @Author .朱孝輝
 * @Blog http://www.cmnbgy.top
 * @Datae 2018/11/14 0014 13:45
 **/
@Configuration
// basePackages :設置爲你的 mapper(主數據源)接口路徑
@MapperScan(basePackages = "top.cmnbgy.springbootibatismulidatasource.mapper.master", sqlSessionTemplateRef  = "master-SqlSessionTemplate")
// ConfigurationProperties:讀取application文件
@ConfigurationProperties(prefix = "spring.datasource.master")
public class MasterDataSource {

    private String url;
      private String username;
    private String password;
    private String driverClassName;

    /* ....... 忽略其餘配置參數*/
    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


    /**
     * 建立主數據源
     * @return
     */
    @Bean(name = "master-DataSource")
    @Primary
   // @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource testDataSource() {
        /**
         *  @Bean:建立bean組件,可設置bean的name,若是不寫name默認爲方法名
         *  @Primary:設置爲優先注入,若是Bean類型有多個,設置@Primary後會將該Bean優先注入,不然會報錯
         *  @ConfigurationProperties:讀取application.properties 屬性封裝成實體類
         *
         *  DataSourceBuilder.create().build() :SpringBoot爲咱們提供了簡便的建立數據源方式
         */
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        return dataSource;
    }

    /**
     *      建立SqlSession工廠
     */
    @Primary
    @Bean(name = "master-SqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("master-DataSource") DataSource dataSource) throws Exception {
        /**
         * @Qualifier:正常狀況下,注入bean時,若是存在多個資源,就會出錯,能夠用@Qualifier指定名字
         */
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/master/*/*.xml"));
        return bean.getObject();
    }

    /**
     *  事務管理
     */
    @Primary
    @Bean(name="master-TransactionManager")
    public DataSourceTransactionManager masterTransactionManager(@Qualifier("master-DataSource") DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
        return dataSourceTransactionManager;
    }

    /**
     *  配置sqlsession模板
     */
    @Primary
    @Bean("master-SqlSessionTemplate")
    public SqlSessionTemplate masterSQLSessionTemplate(@Qualifier("master-SqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

 

從數據源  SlaveDataSource 

package top.cmnbgy.springbootibatismulidatasource.dataSource;

import com.alibaba.druid.pool.DruidDataSource;
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.beans.factory.annotation.Value;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 從數據源配置
 * @ClassName SlaveDataSource
 * @Cescription TODO
 * @Author .朱孝輝
 * @Blog http://www.cmnbgy.top
 * @Datae 2018/11/14 0014 13:46
 **/

@Configuration
@MapperScan(basePackages = "top.cmnbgy.springbootibatismulidatasource.mapper.slave", sqlSessionTemplateRef  = "slave-SqlSessionTemplate")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public class SlaveDataSource {

    private String url;
    private String username;
    private String password;
    private String driverClassName;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    /**
     * 建立主數據源
     * @return
     */
    @Bean(name = "slave-DataSource")
    // @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource testDataSource() {
        /**
         *  @Bean:建立bean組件,可設置bean的name,若是不寫name默認爲方法名
         *  @Primary:設置爲優先注入,若是Bean類型有多個,設置@Primary後會將該Bean優先注入,不然會報錯
         *  @ConfigurationProperties:讀取application.properties 屬性封裝成實體類
         *
         *  DataSourceBuilder.create().build() :SpringBoot爲咱們提供了簡便的建立數據源方式
         */
        System.out.println("================================"+url);
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);// 用戶名
        dataSource.setPassword(password);// 密碼
        dataSource.setDriverClassName(driverClassName);
        return dataSource;
    }

    /**
     *      建立SqlSession工廠
     */
    @Bean(name = "slave-SqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("slave-DataSource") DataSource dataSource) throws Exception {
        /**
         * @Qualifier:
         */
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/slave/*/*.xml"));
        return bean.getObject();
    }

    /**
     *  事務管理
     */
    @Bean(name="slave-TransactionManager")
    public DataSourceTransactionManager masterTransactionManager(@Qualifier("slave-DataSource") DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
        return dataSourceTransactionManager;
    }

    /**
     *  配置sqlsession模板
     */
    @Bean("slave-SqlSessionTemplate")
    public SqlSessionTemplate masterSQLSessionTemplate(@Qualifier("slave-SqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 

 

  • @Configuration用於定義配置類,告訴springboot這是配置類。
  • @ConfigurationProperties:讀取application配置文件
  • @Bean建立bean組件,可設置bean的name,若是不寫name默認爲方法名
  • @Primary設置爲優先注入,若是Bean類型有多個,設置@Primary後會將該Bean優先注入,不然會報錯
  • @ConfigurationProperties讀取application.properties 屬性封裝成實體類
  • @Qualifier正常狀況下,注入bean時,若是存在多個資源,就會出錯,能夠用@Qualifier指定名字
  • @MapperScanibatis提供的註解,註解包路徑 package org.mybatis.spring.annotation;
    • basePackages要掃描mapper類包的路徑
    • sqlSessionTemplateRefsqlSessionTemplateRef Bean的名稱

  注意:關於bean的命名 masterDataSource  之前我是這樣命名的,最後一直報錯,排查後發現spring容器中也有一個 名稱爲masterDataSource的bean,因此起衝突了。

 

   

建立mapper接口和xml

 

建立文件夾 top.cmnbgy.springbootibatismulidatasource.mapper.master 

用於放  數據源 mapper接口類  UsersMapper.java

package top.cmnbgy.springbootibatismulidatasource.mapper.master;

import java.util.List;

/**
 * @ClassName UsersMapper
 * @Cescription TODO
 * @Author .朱孝輝
 * @Blog http://www.cmnbgy.top
 * @Datae 2018/11/15 0015 9:57
 **/
public interface UsersMapper {
    List selectAll();
}

 

建立文件夾 top.cmnbgy.springbootibatismulidatasource.mapper.slave

 再建立一個數據源 mapper接口  Users1Mapper.java

package top.cmnbgy.springbootibatismulidatasource.mapper.slave;

import java.util.List;

/**
 * @ClassName UsersMapper
 * @Cescription TODO
 * @Author .朱孝輝
 * @Blog http://www.cmnbgy.top
 * @Datae 2018/11/15 0015 9:57
 **/
public interface Users1Mapper {
    List selectAll();
}

 

   

 建立mapperXMl

建立 master 文件夾下面 的 UsersMapper.xml  文件 

爲了省步驟,我直接用HashMap 作載體,就不用寫實體類了

<?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="top.cmnbgy.springbootibatismulidatasource.mapper.master.UsersMapper" >
    <select id="selectAll" resultType="map">
        select * from users
    </select>
</mapper>

建立 slave文件夾下面 的 UsersMapper.xml  文件 

<?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="top.cmnbgy.springbootibatismulidatasource.mapper.slave.Users1Mapper" >
    <select id="selectAll" resultType="map">  
        select * from users
    </select>
</mapper>

 

resultType="map"  映射返回類型可使用別名

我在貼一份別名的表,這些都是mybatis 自帶的 別名配置,你也能夠自定義別名 

 https://blog.csdn.net/qq_28885149/article/details/51694733

【ღ( ´・ᴗ・` )比心】

別名 映射的類型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

   

★華麗分割線 ★   注意點


 注意

  檢查下 數據源配置文件(Master | SlaveDataSource)的

 

 看看有沒有對應上,Master  和 Slave 別混淆,若是報 哪一個XML的某個 sql 沒匹配上,請仔細檢查一下以上的路徑是否正確!

 

 

★華麗分割線 ★   最後的測試環節


 

 

 

 

package top.cmnbgy.springbootibatismulidatasource;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.annotations.Select;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import top.cmnbgy.springbootibatismulidatasource.mapper.master.UsersMapper;
import top.cmnbgy.springbootibatismulidatasource.mapper.slave.Users1Mapper;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.awt.image.Kernel;
import java.sql.SQLException;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootIbatisMulidatasourceApplicationTests {

    @Resource(name = "master-DataSource")
    DataSource masterDataSource;

    @Resource(name = "slave-DataSource")
    DataSource slaveDataSource;

    /**
     * 主數據源
     */
    @Autowired
    UsersMapper usersMapper;

    /**
     * 從數據源
     */
    @Autowired
    Users1Mapper users1Mapper;

    @Test
    public void contextLoads() throws SQLException {
        System.out.println("==========================================================");
        System.out.println("主數據源:"+masterDataSource);
        System.out.println("從數據源:"+slaveDataSource);
        // 開啓分頁
        System.out.println("主數據源:");
        Page page = PageHelper.startPage(1,10);
        System.out.println(usersMapper.selectAll());
        usersMapper.selectAll().forEach(item->System.out.println(item));
        System.out.println("總頁數:"+page.getTotal());
        //-----------------------------------------------------------
        System.out.println("從數據源:");
        Page page1 = PageHelper.startPage(1,10);
        System.out.println(users1Mapper.selectAll().toString());
        System.out.println(page1.getTotal());
        System.out.println("總頁數:"+page1.getTotal());
        users1Mapper.selectAll().forEach(item->System.out.println(item));
        System.out.println("==========================================================");
    }

}

 

 

 

 

 

 ok 測試!!!!!!!

 

     PageHelper文檔:    https://pagehelper.github.io/

   某個大神的SpringBoot 技術博客 :http://tengj.top/2017/02/26/springboot1/

  

 

★華麗分割線 ★   結尾


    教程結束!

 喜歡該博文的同窗和點贊關注ღ( ´・ᴗ・` )比心

 文中若有不足,歡迎指正和討論!❤

 做者QQ:1983127490 

 代碼以上傳碼雲

 碼雲:https://gitee.com/gezi441/spring-boot-ibatis-mulidatasource

相關文章
相關標籤/搜索