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


 

前言:

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

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

思考:

  1、如果從傳統的單數據源轉換為多數據源,以前使用boot只用導包寫配置文件boot會幫我們自動配置,如果不用自動配置我們改怎么配呢?

  2、怎么結合mybatis分頁插件一起使用呢?

  .................

  

項目目錄結構

 

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

      

創建2個數據庫  

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個數據源  test1、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

            

   

 


免責聲明!

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



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