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

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

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

   

★华丽分割线 ★   注意点


 注意

  检查下 数据源配置文件(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

            

   

 

转载于:https://www.cnblogs.com/thirteen-zxh/p/9967598.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值