当前位置:   article > 正文

ShardingSphere系列03:ShardingJdbc+MybatisPlus实现多数据源_shardingsphere 多数据源

shardingsphere 多数据源

Mybatisplus+多数据源

整合步骤
基础数据准备
  • 创建表order_info,同时创建同样数据结构的order_info_0,order_info_1,order_info_2,order_info_3
CREATE TABLE `order_info` (
  `id` bigint NOT NULL COMMENT 'id',
  `name` varchar(32) DEFAULT NULL COMMENT '名称',
  `num` int DEFAULT NULL COMMENT '数量',
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里的分表逻辑是根据id取余,分成4个表。

1、需要依赖
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--导入mybatisplus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

<!--        shardingjdbc-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.1.2</version>
        </dependency>

<!--        druid数据源,需要导入,否则shardingjdbc无法找到druid数据源会报错-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.9</version>
        </dependency>

<!-- mybatisplus 动态数据源 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
2、基础类准备
package com.walker.mbpsharding.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

/**
 * @Author: WalkerShen
 * @DATE: 2022/3/29
 * @Description:
 **/
@Data
//使用tableName代表映射的mysql的表
@TableName("order_info")
public class OrderInfo {
    private Long id;
    private String name;
    private Integer num;
    private Date createTime;
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
package com.walker.mbpsharding.mapper;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.walker.mbpsharding.entity.OrderInfo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @Author: WalkerShen
 * @DATE: 2022/3/29
 * @Description: 创建mapper接口,
 **/

//使用@Mapper,注入容器
@Mapper
//继承BaseMapper类,可以获取BaseMapper中的方法
public interface OrderInfoMapper extends BaseMapper<OrderInfo> {
    
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
package com.walker.mbpsharding.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.walker.mbpsharding.entity.OrderInfo;

import java.util.List;

public interface OrderInfoService extends IService<OrderInfo> {

    List<OrderInfo> listSharding();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
package com.walker.mbpsharding.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.walker.mbpsharding.entity.OrderInfo;
import com.walker.mbpsharding.mapper.OrderInfoMapper;
import org.springframework.stereotype.Service;

import java.util.List;

//1、使用@Service注入容器
@Service
//2、继承serviceImpl
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService{


    // 使用@DS指定需要执行的数据源
    @DS(value="sharding")
    @Override
    public List<OrderInfo> listSharding() {
        return list();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 这里对listSharding方法使用了@DS注解,让其使用sharding数据源去执行sql

OrderInfoMapper.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">
<!--namespace:命名空间,用来映射对应的mapper
相当于将mapper和mapper.xml连接起来,这一步很重要-->
<mapper namespace="com.walker.mbpsharding.mapper.OrderInfoMapper">

</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

image.png
注意:xml文件的位置需要和配置文件配置的一样,否则找不到就会报Mapper的Bean找不到的错误

3、动态数据源配置类编写
package com.walker.mbpsharding.config;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.apache.shardingsphere.driver.jdbc.adapter.AbstractDataSourceAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Map;

/**
 * 动态数据源配置:
 *
 * 使用{@link com.baomidou.dynamic.datasource.annotation.DS}注解,切换数据源
 *
 */
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class,
        SpringBootConfiguration.class})
public class DataSourceConfiguration {
    // 分表数据源名称
    private static final String SHARDING_DATA_SOURCE_NAME = "sharding";

    //mybatisplus 动态数据源配置项
    @Autowired
    private DynamicDataSourceProperties properties;

    // shardingjdbc的数据源
    @Lazy
    @Resource(name = "shardingSphereDataSource")
    AbstractDataSourceAdapter shardingSphereDataSource;


    // 动态数据源提供者bean注册
    @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider() {
        // 首先从mybatisplus的动态数据源先获取
        Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
        return new AbstractDataSourceProvider() {
            @Override
            public Map<String, DataSource> loadDataSources() {
                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
                // 然后将 shardingjdbc 管理的数据源也交给动态数据源管理
                dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingSphereDataSource);
                return dataSourceMap;
            }
        };
    }



    // 数据源配置 @Primary 代表优先使用该bean 
    @Primary
    @Bean
    public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
//        首选数据源
        dataSource.setPrimary(properties.getPrimary());
        dataSource.setStrict(properties.getStrict());
        dataSource.setStrategy(properties.getStrategy());
//        配置数据源提供者
        dataSource.setProvider(dynamicDataSourceProvider);
        dataSource.setP6spy(properties.getP6spy());
        dataSource.setSeata(properties.getSeata());
        return dataSource;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

其实就是分别获取mybatisplus的数据源和sharding的数据源,然后将sharding的数据源加入到mybatisplus的动态数据源Map中,然后就可以使用@DS注解去指定数据源了

4、application.yaml配置

spring:
  autoconfigure: # 排除druid 否则报错
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
#  注意格式一定要配好,这里有一个datasource 然后再dynamic,后面再来了一个datasource 才到了配置数据源
  datasource:
  
  # 1、mybatisplus动态数据源的配置
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/table_sharding?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimeZone=UTC
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

  shardingsphere:
    # 开启sql打印
    enabled: true
    props:
      # 是否显示sql
      sql-show: true
 # 2、shardingjdbc的数据源的配置
    datasource:
      #      数据源名称
      names: sharding
      #      数据源实例: 如果这里还有master
      sharding:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class: com.mysql.cj.jdbc.Driver
        #        使用Druid,不能使用jdbc-url 得使用url
        url: jdbc:mysql://localhost:3306/table_sharding?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
        username: root
        password: 123456
    # 分片规则
    rules:
      sharding:
        #        对表进行分片
        tables:
          #          逻辑表名,代表的是需要分表的名称
          order_info:
            #            实际节点:这里代表的是 会使用sharding数据源中 order_info表 细分为0~3 4个表
            actual-data-nodes: sharding.order_info_$->{0..3}
            #            表策略
            table-strategy:
              #              标准表策略
              standard:
                #                分表的列
                sharding-column: id
                #                分片算法名称: 来源于下面的sharding-algorithms
                sharding-algorithm-name: alg_hash_mod
            key-generate-strategy: # 主键生成策略
              column: id  # 主键列
              key-generator-name: snowflake  # 策略算法名称(推荐使用雪花算法)
        #              主键生成规则,SNOWFLAKE 雪花算法
        key-generators:
          snowflake:
            type: SNOWFLAKE
        #            分片算法
        sharding-algorithms:
          alg_hash_mod:
            #            类型:hash取余  类似于获取一个列的数,假如是3  3%4=0 数据就会进入第0个表
            type: HASH_MOD
            #            分片的数量,因为是4个表,所以是4
            props:
              sharding-count: 4

# mybatisplus配置
mybatis-plus:
  # 配置xml路径
  mapper-locations: classpath*:/mapper/*Mapper.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
5、测试
package com.walker.mbpsharding;

import com.walker.mbpsharding.entity.OrderInfo;
import com.walker.mbpsharding.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@Slf4j
@SpringBootTest
class MybatisplusShardingApplicationTests {

    @Autowired
    private OrderInfoService orderInfoService;


    @Test
    public void list(){
        List<OrderInfo> list = orderInfoService.list();
        log.info("返回结果:{}",list);
    }

    @Test
    public void sharding(){
        List<OrderInfo> list = orderInfoService.listSharding();
        log.info("返回结果:{}",list);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

执行list方法:
image.png

执行sharding方法
image.png
可以看到,使用分表的原则去查询数据

SELECT  id,name,num,create_time  FROM order_info_0 UNION ALL SELECT  id,name,num,create_time  FROM order_info_1 UNION ALL SELECT  id,name,num,create_time  FROM order_info_2 UNION ALL SELECT  id,name,num,create_time  FROM order_info_3
  • 1
疑问
如果需要配置druid数据源的话,需要如何配置呢?

我们可以查看DynamicDataSourceProperties类,可以看到关于Druid的配置
image.png

所以我们要如此配置:
放在指定的数据源下面: druid.xxx
image.png

spring:
#  注意格式一定要配好,这里有一个datasource 然后再dynamic,后面再来了一个datasource 才到了配置数据源
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/table_sharding?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimeZone=UTC
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          druid:
            # 初始连接数
            initialSize: 5
            # 最小连接池数量
            minIdle: 10
            # 最大连接池数量
            maxActive: 20
            # 配置获取连接等待超时的时间
            maxWait: 60000
            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
            timeBetweenEvictionRunsMillis: 60000
            # 配置一个连接在池中最小生存的时间,单位是毫秒
            minEvictableIdleTimeMillis: 300000
            # 配置一个连接在池中最大生存的时间,单位是毫秒
            maxEvictableIdleTimeMillis: 900000
            # 配置检测连接是否有效
            validationQuery: SELECT 1 FROM DUAL
            testWhileIdle: true
            testOnBorrow: false
            testOnReturn: false
            wall:
              multi-statement-allow: true
              condition-and-alway-true-allow: true
            stat:
              # 慢SQL记录
              logSlowSql: true
              slowSqlMillis: 1000
              mergeSql: true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
参考文档

mybatisplus多数据源配置参考:
https://baomidou.com/pages/a61e1b/

总结:

整合Mybatisplus应该是比较常见的场景了,现在大部分企业都有使用mp。

也可以看看历史文章学习一下哦~
ShardingSphere系列01:Shardingjdbc实现分表(含项目实践)

ShardingSphere系列02:ShardingJdbc+Mybatis实现多数据源

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/604296
推荐阅读
相关标签
  

闽ICP备14008679号