springboot整合ShardingSphere5.2.1(最新版)

内容包含分表配置文件类型和自定义类型两种方法
无法直接上次代码,疯狂贴图

springboot整合ShardingSphere5.2.1(最新版)_第1张图片

config
MyBaseMapper

package cn.com.lyb.config;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

public interface MyBaseMapper<T> extends BaseMapper<T> {

    /**
     * 批量插入,相当于insertList
     */
    int insertBatchSomeColumn(List<T> entityList);
}

MybatisPlusConfig

package cn.com.lyb.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class MybatisPlusConfig extends DefaultSqlInjector {
    /**
     * mybatisPlus分页配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setOptimizeJoin(true);
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(true);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        return interceptor;
    }
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        // 注意:此SQL注入器继承了DefaultSqlInjector(默认注入器),调用了DefaultSqlInjector的getMethodList方法,保留了mybatis-plus的自带方法
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        // 注入InsertBatchSomeColumn
        // 在!t.isLogicDelete()表示不要逻辑删除字段,!"update_time".equals(t.getColumn())表示不要字段名为 update_time 的字段
        methodList.add(new InsertBatchSomeColumn(t -> !t.isLogicDelete() && !"update_time".equals(t.getColumn())));
        return methodList;
    }
}

TableShardingAlgorithm

package cn.com.lyb.config;



import com.google.common.collect.Range;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;


import java.util.*;
import java.util.stream.Collectors;

/**
 * 分表逻辑配置类
 * 此类生效必须配置/resource/META_INF.service/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
 * 不然启动报错:SPI-00001: No implementation class load from SPI `org.apache xxx
 */
public class TableShardingAlgorithm implements StandardShardingAlgorithm<Long>{

    private static final String TABLE_NAME = "base_";

    private final static String CUT = "_";

    private Properties props = new Properties();

    /*
     *availableTargetNames:配置文件中定义的表名称集合
     *shardingValue:insert,select,update,delate时,pid字段值
     *函数返回值:返回函数值shardingValue对应的表名。比如 pid%10=,返回表名base_3
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        if (CollectionUtils.isEmpty(availableTargetNames) || (shardingValue == null || shardingValue.getValue() == null)) {
            throw new IllegalArgumentException("sharding jdbc not find logic table,please check config");
        }
        String shard = null;
        if (shardingValue != null) {
            Long value = shardingValue.getValue();
            shard = String.valueOf(value % 10);
            return TABLE_NAME + shard;
        } else {
            throw new UnsupportedOperationException("传递参数有误");
        }
    }

    /*
     *availableTargetNames:配置文件中定义的表名称集合
     *函数返回值:返回函数值rangeShardingValue 对应的表名集合,比如获取到的pid集合取模为1,2,3,就返回base_1,base_2,base_3
     */
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> rangeShardingValue) {
        Collection<String> resList = new ArrayList<>();
        // 获取所有表的后缀数字
        List<Integer> intList = availableTargetNames.stream()
                .map(table -> Integer.valueOf(table.substring(table.lastIndexOf(CUT) + 1)))
                .collect(Collectors.toList());
        Range<Long> valueRange = rangeShardingValue.getValueRange();
        Long startLong = valueRange.lowerEndpoint();
        int startInteger = (int) (startLong % 10);
        Long endLong = valueRange.upperEndpoint();
        int endInteger = (int) (endLong % 10);
        if (!intList.contains(startInteger) || !intList.contains(endInteger)) {
            throw new RuntimeException("存在无效参数");
        }
        for (String tableName : availableTargetNames) {
            for (int i = startInteger; i <= endInteger; i++) {
                String tag = String.valueOf(i);
                if (tableName.substring(tableName.lastIndexOf(CUT)+1).equals(tag)) {
                    resList.add(tableName);
                }
            }
        }
        if (CollectionUtils.isEmpty(resList)) {
            throw new RuntimeException("参数分表结果为空");
        }
        return resList;
    }

    @Override
    public Properties getProps() {
        return props;
    }

    @Override
    public void init(Properties properties) {

    }


}

controller

package cn.com.lyb.controller;

import cn.com.lyb.entity.BaseEntity;
import cn.com.lyb.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class BaseController {

    @Autowired
    private BaseService baseService;

    @GetMapping("/batchSave")
    private void save(){
        baseService.save();
    }

    @PostMapping("/selectByIdAndPid")
    private List<BaseEntity> selectByIdAndPid(Long id, Long pid){
        List<BaseEntity> baseEntities = baseService.selectByIdandPid(id, pid);
        return baseEntities;
    }

    @PostMapping("/selectByPis")
    private List<BaseEntity> selectByPis(String pids){
        List<BaseEntity> baseEntities = baseService.selectByPids(pids);
        return baseEntities;
    }

    @PostMapping("/selectAll")
    private List<BaseEntity> selectAll(){
        List<BaseEntity> baseEntities = baseService.selectAll();
        return baseEntities;
    }

    @PostMapping("/selectRangPid")
    private List<BaseEntity> selectRangPid(Long startPid, Long endPid){
        List<BaseEntity> baseEntities = baseService.selectRangPid(startPid, endPid);
        return baseEntities;
    }
}

entity

package cn.com.lyb.entity;

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

@TableName(value = "base")
public class BaseEntity {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    private Integer divideId;

    private String type;

    private Long pid;
    private String pids;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getDivideId() {
        return divideId;
    }

    public void setDivideId(Integer divideId) {
        this.divideId = divideId;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Long getPid() {
        return pid;
    }

    public void setPid(Long pid) {
        this.pid = pid;
    }

    public String getPids() {
        return pids;
    }

    public void setPids(String pids) {
        this.pids = pids;
    }
}

dao

package cn.com.lyb.dao;

import cn.com.lyb.config.MyBaseMapper;
import cn.com.lyb.entity.BaseEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface BaseDao extends MyBaseMapper<BaseEntity> {

}

service

package cn.com.lyb.service;

import cn.com.lyb.entity.BaseEntity;

import java.util.List;

public interface BaseService {
    void save();

    List<BaseEntity> selectByIdandPid(Long id, Long pid);

    List<BaseEntity> selectByPids(String pids);

    List<BaseEntity> selectAll();

    List<BaseEntity> selectRangPid(Long startPid, Long endPid);
}

impl

package cn.com.lyb.service.impl;

import cn.com.lyb.dao.BaseDao;
import cn.com.lyb.entity.BaseEntity;
import cn.com.lyb.service.BaseService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class BaseServiceImpl implements BaseService {

    @Autowired
    private BaseDao baseDao;

    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void save() {
        for (int i = 0;i<10;i++){
            BaseEntity baseEntity = new BaseEntity();
            baseEntity.setPid(0L);
            baseEntity.setType("schema");
            baseEntity.setDivideId((int) (baseEntity.getPid()%10));
            baseEntity.setPids("0");
            baseDao.insert(baseEntity);
            this.saveTable(baseEntity.getId(), baseEntity.getPids());
        }
    }

    @Override
    public List<BaseEntity> selectByIdandPid(Long id, Long pid) {
        return baseDao.selectList(new QueryWrapper<BaseEntity>().eq("id",id)
                .eq("pid",pid));
    }

    @Override
    public List<BaseEntity> selectByPids(String pids) {
        List<Long> pidList = Arrays.stream(pids.split(","))
                .map(Long::parseLong)
                .collect(Collectors.toList());
        return baseDao.selectList(new QueryWrapper<BaseEntity>()
                .in("pid",pidList));
    }

    @Override
    public List<BaseEntity> selectAll() {
        return baseDao.selectList(new QueryWrapper<BaseEntity>());
    }

    @Override
    public List<BaseEntity> selectRangPid(Long startPid, Long endPid) {
        return baseDao.selectList(new QueryWrapper<BaseEntity>()
                .gt("pid",startPid)
                .lt("pid",endPid));
    }

    public void saveTable(Long id, String pids) {
        for (int i = 0; i < 10; i++) {
            BaseEntity baseEntity = new BaseEntity();
            baseEntity.setPid(id);
            baseEntity.setType("table");
            baseEntity.setDivideId((int) (baseEntity.getPid()%10));
            baseEntity.setPids(pids + "," +id);
            baseDao.insert(baseEntity);
            this.saveColumn(baseEntity.getId(), baseEntity.getPids());
        }
    }

    public void saveColumn(Long id, String pids) {
        List<BaseEntity> insertList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            BaseEntity baseEntity = new BaseEntity();
            baseEntity.setPid(id);
            baseEntity.setType("column");
            baseEntity.setDivideId((int) (baseEntity.getPid()%10));
            baseEntity.setPids(pids + "," +id);
            insertList.add(baseEntity);
        }
        baseDao.insertBatchSomeColumn(insertList);
    }
}

Main

package cn.com.lyb;


import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
@MapperScan("cn.com.lyb.**.dao")
public class Main {
    public static void main(String[] args) {
        try{
            SpringApplication.run(Main.class, args);
        }catch (Exception e){
            System.out.println("报错原因:" + e);
        }
    }
}

配置文件

server:
  port: 9090
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://17x.xx.xx.xx:3367/lyb-base?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: 123456
  sharding-sphere:
    # 是否启用 Sharding
    enabled: true
    # 打印sql
    props:
      sql-show: true
    datasource:
      names: ds
      ds:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: ${spring.datasource.driver-class-name}
        url: ${spring.datasource.url}
        username: ${spring.datasource.username}
        password: ${spring.datasource.password}
    rules:
      sharding:
        defaultDataSourceName: ds
        # 表策略配置
        tables:
          # base 是逻辑表,数据库存在的是base_0,base_1,...
          base:
            actualDataNodes: ds.base_$->{0..9}
            tableStrategy:
              # 使用标准分片策略
              standard:
                # 配置分片字段
                shardingColumn: pid
                # 分片算法名称,不支持大写字母和下划线,否则启动就会报错
                shardingAlgorithmName: sharding-altorithm
        # 分片算法配置
        shardingAlgorithms:
          # 分片算法名称,不支持大写字母和下划线,否则启动就会报错
          sharding-altorithm:
            # 类型:配置文件处理,简单的可采用此类型
#            type: INLINE
#            props:
#                #分片表达式,用pid对10取模,然后分散到10个表中
#                algorithm-expression: base_$->{pid % 10}
#                allow-range-query-with-inline-sharding: true
            # 类型:自定义策略
            type: CLASS_BASED
            props:
              # 分片策略
              strategy: standard
              # 分片算法类
              algorithmClassName: cn.com.lyb.config.TableShardingAlgorithm

#mybatis-plus配置控制台打印完整带参数SQL语句
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


pom.xml


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.2.5.RELEASEversion>
        <relativePath/> 
    parent>
    <groupId>cn.com.lybgroupId>
    <artifactId>springboot-shard-jdbc-5.2.1artifactId>
    <version>1.0-SNAPSHOTversion>

    <properties>
        <snakeyaml.version>1.33snakeyaml.version>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-jdbcartifactId>
        dependency>

        
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.4.3version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.49version>
        dependency>

        <dependency>
            <groupId>org.apache.shardingspheregroupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starterartifactId>
            <version>5.2.1version>
        dependency>



        <dependency>
            <groupId>org.apache.tomcatgroupId>
            <artifactId>tomcat-dbcpartifactId>
            <version>10.0.16version>
        dependency>

        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-allartifactId>
            <version>5.6.3version>
        dependency>

        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>

    dependencies>

project>

你可能感兴趣的:(spring,boot,后端,java)