Spring Boot整合Sharding-JDBC實現分庫分表+讀寫分離org.apache.shardingsphere+mybatis-plus(4)


在本文中使用Spring Boot 2.4.1+MyBatis-plus+Druid+Sharding-JDBC+MySQL進行讀寫分離的案件講解。

1、數據庫准備

       1、192.168.8.162  test1主

       2、192.168.8.134  test1從

       3、192.168.8.176  test1從

       4、192.168.8.162  test2主

       5、192.168.8.134  test2從

       6、192.168.8.176  test2從

2、准備分庫分表

復制代碼
USE `test1`;

DROP TABLE IF EXISTS `t_user_0`;
CREATE TABLE `t_user_0` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user_1`;
CREATE TABLE `t_user_1` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user_2`;
CREATE TABLE `t_user_2` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user_3`;
CREATE TABLE `t_user_3` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


USE `test2`;

DROP TABLE IF EXISTS `t_user_0`;
CREATE TABLE `t_user_0` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user_1`;
CREATE TABLE `t_user_1` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user_2`;
CREATE TABLE `t_user_2` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_user_3`;
CREATE TABLE `t_user_3` (
  `id` int(10) NOT NULL,
  `name` varchar(50) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
復制代碼

3、上代碼

1、pom.xml配置引入maven依賴

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <druid.version>1.1.9</druid.version>
        <mybatis-plus.version>3.1.1</mybatis-plus.version>
        <mybatis-plus-stater.version>3.1.2</mybatis-plus-stater.version>
        <lombok.version>1.16.18</lombok.version>
        <mybatisplus-spring-boot-starter.version>1.0.5</mybatisplus-spring-boot-starter.version>
    </properties>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- Mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatisplus-spring-boot-starter</artifactId>
            <version>${mybatisplus-spring-boot-starter.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-stater.version}</version>
        </dependency>

        <!--shardingsphere數據分片、脫敏工具-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.0</version>
        </dependency>

2、在application.yml中配置使用mybatis-plus及引用數據源及分庫分表信息

spring:
 # 配置說明地址 https://test1.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/configuration/config-spring-boot/#%E6%95%B0%E6%8D%AE%E5%88%86%E7%89%87
  shardingsphere:
   # 數據庫
    datasource:
     # 主庫1 ,master數據庫
      master0:
        ###  數據源類別
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.8.162:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: root
        password: root
       # 主庫1從庫1 ,slave數據庫
      master0slave0:
        ###  數據源類別
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.8.134:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: root
        password: root
       # 主庫1從庫2 ,slave數據庫
      master0slave1:
        ###  數據源類別
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.8.176:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: root
        password: root
         # 主庫2 ,master數據庫
      master1:
        ###  數據源類別
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.8.162:3306/test2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: root
        password: root
       # 主庫2從庫1 ,slave數據庫
      master1slave0:
        ###  數據源類別
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.8.134:3306/test2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: root
        password: root
       # 主庫2從庫2 ,slave數據庫
      master1slave1:
        ###  數據源類別
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.8.176:3306/test2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: root
        password: root
        # 數據庫的別名
      names: master0,master0slave0,master0slave1,master1,master1slave0,master1slave1
    sharding:
      # 設置綁定表,用逗號分割
      binding-tables: t_user
      master-slave-rules:
        ds0:
          name: ds0datasource
      # 查詢時的負載均衡算法,目前有2種算法,round_robin(輪詢)和random(隨機),
      # 算法接口是io.shardingjdbc.core.api.algorithm.masterslave.MasterSlaveLoadBalanceAlgorithm。
      # 實現類有RandomMasterSlaveLoadBalanceAlgorithm 和 RoundRobinMasterSlaveLoadBalanceAlgorithm。
          load-balance-algorithm-type: round_robin
       # 主數據源名稱
          master-data-source-name: master0
          # 從數據源名稱,多個用逗號隔開
          slave-data-source-names: master0slave0, master0slave1
        ds1:
          name: ds1datasource
      # 查詢時的負載均衡算法,目前有2種算法,round_robin(輪詢)和random(隨機),
      # 算法接口是io.shardingjdbc.core.api.algorithm.masterslave.MasterSlaveLoadBalanceAlgorithm。
      # 實現類有RandomMasterSlaveLoadBalanceAlgorithm 和 RoundRobinMasterSlaveLoadBalanceAlgorithm。
          load-balance-algorithm-type: round_robin
       # 主數據源名稱
          master-data-source-name: master1
          # 從數據源名稱,多個用逗號隔開
          slave-data-source-names: master1slave0,master1slave1
      tables:
        ### t_user分庫分表配置
        t_user:
          actual-data-nodes: ds$->{0..1}.t_user_$->{0..3}
          database-strategy:
            standard:
              precise-algorithm-class-name: com.demo.shardingjdbc.MyDBPreciseShardingAlgorithm
              sharding-column: id
          table-strategy:
            standard:
              precise-algorithm-class-name: com.demo.shardingjdbc.MyTablePreciseShardingAlgorithm
              sharding-column: id
#### mybatis-plus ###
mybatis-plus:
  # 如果是放在src/main/java目錄下 classpath:/com/yourpackage/*/mapper/*Mapper.xml
  # 如果是放在resource目錄 classpath:/mapper/*Mapper.xml
  mapper-locations: classpath:mapper/*.xml
  #實體掃描,多個package用逗號或者分號分隔
  type-aliases-package: com.demo.shardingjdbc.entity
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
  #主鍵類型  0:"數據庫ID自增", 1:"用戶輸入ID",2:"全局唯一ID (數字類型唯一ID)", 3:"全局唯一ID UUID";
  global-config:
    db-config:
      id-type: auto
      #字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
      field-strategy: not-empty
      #駝峰下划線轉換
      column-underline: true
      #邏輯刪除配置
      logic-delete-value: 0
      logic-not-delete-value: 1
      db-type: mysql
  #刷新mapper 調試神器
  refresh: false

3、配置分庫分表分片規則(結合application.yml)

分庫規則(結合pplication.yml中database-strategy)

package com.demo.shardingjdbc;



import java.util.Collection;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

/**
 * 自定義實現 精准分片算法(PreciseShardingAlgorithm)接口
 * 數據表table的精准分片
 * @author hzy
 *
 */
public class MyDBPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
        for (String tableName : availableTargetNames) {
            if (tableName.endsWith(shardingValue.getValue() % 2 + "")) {
                return tableName;
            }
        }
        throw new IllegalArgumentException();
    }

}

分表規則(結合pplication.yml中table-strategy)

package com.demo.shardingjdbc;



import java.util.Collection;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

/**
 * 自定義實現 精准分片算法(PreciseShardingAlgorithm)接口
 * 數據表table的精准分片
 * @author hzy
 *
 */
public class MyTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
        for (String tableName : availableTargetNames) {
            if (tableName.endsWith(shardingValue.getValue() % 4 + "")) {
                return tableName;
            }
        }
        throw new IllegalArgumentException();
    }

}

4、mybatis-plus操作數據庫配置

User.java

復制代碼
package com.demo.shardingjdbc.entity;

import java.io.Serializable;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;

/**
 * @Description: (User)實體類
 * @Version 1.0
 */
@Data
@TableName("t_user")
public class User implements Serializable {

    private static final long serialVersionUID = 358157380505039579L;

    /**
     * 用戶id
     */
    @TableId(type = IdType.INPUT)
    private Integer id;

    /**
     * 用戶名稱
     */
    private String name;


    /**
     * 性別
     */
    private String sex;

}
復制代碼

mapper

復制代碼
package com.demo.shardingjdbc.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.demo.shardingjdbc.entity.User;

/**
 * (t_user)表數據庫訪問層
 *
 */
public interface UserMapper extends BaseMapper<User> {

}
復制代碼

5、mybatis-plus配置MybatisPlusConfig

復制代碼
package com.demo.shardingjdbc.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @Description:
 */

//Spring boot方式
@EnableTransactionManagement
@Configuration
//掃描的mapper文件路徑
@MapperScan(value = "com.demo.shardingjdbc.mapper")
public class MybatisPlusConfig {

    /**
     * 分頁插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
復制代碼

6、service層

復制代碼
package com.demo.shardingjdbc.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.demo.shardingjdbc.entity.User;
import com.demo.shardingjdbc.mapper.UserMapper;
import com.demo.shardingjdbc.service.UserService;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> selectList() {
        QueryWrapper<User> wrapper = new QueryWrapper<User>();
        wrapper.orderByAsc("id");
        List<User> users = userMapper.selectList(wrapper);
        return users;
    }

    @Override
    public int insert(User user) {
        return userMapper.insert(user);
    }

}
復制代碼

7、controller控制層

復制代碼
package com.demo.shardingjdbc.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.demo.shardingjdbc.entity.User;
import com.demo.shardingjdbc.service.UserService;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName TestController
 * @Description TestController
 * @Version
 */
@RestController
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 用戶列表
     * 
     * @return
     */
    @RequestMapping("/userList")
    public List<User> userList() {
        log.info("********TestController userList()");
        List<User> users = userService.selectList();
        return users;
    }

    /**
     * 保存用戶
     * 
     * @return
     */
    @GetMapping("/add")
    public Object add() {
        int num = 0;
        for (int i = 1; i <= 300; i++) {
            User user = new User();
            user.setId(i);
            user.setName("hzy" + (i));
            String sex = (i % 2 == 0) ? "男" : "女";
            user.setSex(sex);

            int resutl = userService.insert(user);
            log.info("insert:" + user.toString() + " result:" + resutl);
            num = num + resutl;
        }
        return num;
    }
}
復制代碼

完成。在瀏覽器上執行localhost:8080/add,然后去數據庫中查詢,可以看到test1.t_user_0、test1.t_user_2、test2.t_user_1、test2.t_user_3分別插入了數據。

   然后訪問localhost:8080/userList,可以查詢數據庫中四個表中的所有數據。可見Sharding-JDBC在插入數據的時候,根據數據分庫分表策略,將數據存儲在不同庫不同表中,查詢時將數據庫從多個表中查詢並聚合。


免責聲明!

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



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