Spring Boot整合Sharding-JDBC实现数据分表+读写分离org.apache.shardingsphere+mybatis-plus(3)

在本文中使用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从

2、准备分表

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 ,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
       # 从库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
        # 数据库的别名
      names: master0,master0slave0,master0slave1
    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
        # 从数据源名称,多个用逗号隔开
      tables:
        ### t_user分表配置
        t_user:
          actual-data-nodes: ds0.t_user_$->{0..3}
          table-strategy:
            standard:
              precise-algorithm-class-name: com.demo.shardingjdbc.MyPreciseShardingAlgorithm
              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)

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 MyPreciseShardingAlgorithm 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 <= 150; 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,然后去数据库中查询,可以看到t_user_0、t_user_1、t_user_2、t_user_3分别插入了数据。
然后访问localhost:8080/userList,可以查询数据库中四个表中的所有数据。可见Sharding-JDBC在插入数据的时候,根据数据分表策略,将数据存储在不同的表中,查询的时候将数据库从多个表中查询并聚合.

原文地址:https://www.cnblogs.com/h-z-y/p/14292643.html