分库分表、读写分离--ShardingJDBC

1. 项目准备

1.1 建立数据库表

建立user_manage数据库,在该库中建立1张表app_user用来做分库前的测试,另外建12张按月份命名的表app_user_2024XX用来做分库。

CREATE DATABASE IF NOT EXISTS user_manage
CHARACTER SET utf8
COLLATE utf8_general_ci;

USE user_manage;

CREATE TABLE `app_user` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202401` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202402` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202403` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202404` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202405` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202406` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202407` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202408` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202409` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202410` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202411` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

CREATE TABLE `app_user_202412` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(255) NOT NULL,
    `age` INT(10) NOT NULL,
    `sex` CHAR(1) NOT NULL,
    `address` VARCHAR(100) DEFAULT NULL,
    `phone` VARCHAR(20) DEFAULT NULL,
    `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

在这里插入图片描述

1.2 项目搭建-集成mybatisplus

目录结构
在这里插入图片描述
pom文件

<?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>com.gzdemo</groupId>
    <artifactId>shardingjdbc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <lombok.version>1.18.8</lombok.version>
        <mysql.version>5.1.46</mysql.version>
        <mybatis.version>3.5.1</mybatis.version>
        <mybatis.plus.version>3.4.1</mybatis.plus.version>
    </properties>

    <!-- 继承Spring boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

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

        <!-- Mysql 数据库 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>
    </dependencies>
</project>

application.yml

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.200.131:3306/user_manage?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    username: root
    password: root
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  # 设置别名包扫描路径,通过该属性可以给包中的类注册别名
  type-aliases-package: com.gzdemo.shardingdemo.pojo

AppUser

import lombok.Data;
import java.util.Date;

@Data
//默认映射到app_user表
public class AppUser {

    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    private String address;
    private String phone;
    private Date create_time;
    private Date update_time;
    private Short deleted;
}

AppUserService

public interface AppUserService extends IService<AppUser> {

    boolean addOne(AppUser appUser);
}

AppUserServiceImpl

@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements AppUserService {

    @Autowired
    AppUserMapper appUserMapper;

    @Override
    public boolean addOne(AppUser appUser){
        return appUserMapper.insertOne(appUser);
    }
}

AppUserMapper

@Mapper
public interface AppUserMapper extends BaseMapper<AppUser> {

    boolean insertOne(@Param("user") AppUser appUser);
}

AppUserMapper.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="com.gzdemo.shardingdemo.dao.AppUserMapper">

    <insert id="insertOne" parameterType="com.gzdemo.shardingdemo.pojo.AppUser">
        insert into `app_user`
            (id,name,age,sex,address,phone,create_time,update_time,deleted)
        values(#{user.id},#{user.name},#{user.age},#{user.sex},#{user.address},#{user.phone},
               #{user.create_time},#{user.update_time},#{user.deleted});
    </insert>
</mapper>

AppUserController

@RestController
@RequestMapping("/appUser")
public class AppUserController {

    @Autowired
    AppUserService appUserService;

    @PostMapping("/add")
    public String addAppUser(@RequestBody AppUser appUser){

		appUser.setCreate_time(new Date());
        appUser.setUpdate_time(new Date());
        appUserService.save(appUser); //mybatisplus生成

        appUser.setId(appUser.getId()+1000);
        appUserService.addOne(appUser); //手写的sql
        return "成功";
    }
}

ShardingJdbcDemoApplication

@SpringBootApplication
public class ShardingJdbcDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShardingJdbcDemoApplication.class,args);
    }
}

1.3 postman测试

在这里插入图片描述
数据插入到了app_user表中,mybatisplus没问题
在这里插入图片描述

2. 分库分表实战

添加依赖

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

<!--druid-->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid</artifactId>
	<version>1.1.21</version>
</dependency>

2.1 分表

更改application.yml配置
包括配置数据源、配置逻辑表、配置分片算法
在这里插入图片描述
测试
在这里插入图片描述
查看数据库,发现数据被插入到app_user_202406表里
在这里插入图片描述

2.2 分库

再新建3个数据库,接下来将所有数据分在4个库里。
在这里插入图片描述

更改配置

  • 添加数据源
    在这里插入图片描述
  • 设置分库策略
    在这里插入图片描述
  • 配置分库算法
    这里的算法是取appUser的id的hash值除以取模4求余,再取绝对值,根据结果放在ds0,ds1,ds2,ds3库里
    在这里插入图片描述
    测试
    写一个mapping测试
@PostMapping("/addBatch")
    public String addAppUser(){
        List<AppUser> list = new ArrayList<>();
        for (int i = 0;i<100;i++){
            AppUser appUser = new AppUser();
            appUser.setId(11001+i);
            System.out.print(Math.abs(appUser.hashCode()%4)+",");
            appUser.setSex("0");
            appUser.setName("zhangsan"+i);
            appUser.setAge(25);
            appUser.setDeleted((short)0);
            appUser.setCreate_time(new Date());
            list.add(appUser);
        }

        appUserService.saveBatch(list);
        return "成功";

发送请求
在这里插入图片描述查看数据库,发现4个库的app_user_202406表里都有数据
在这里插入图片描述

2.3 分库分表后读取数据

@GetMapping("/list")
    public List<AppUser> list(){
        return appUserService.list();
    }

测试发现把所有分库的所有表都读取出来了

在这里插入图片描述

2.4 分库分表完整配置

server:
  port: 8080

spring:
  shardingsphere:
    datasource:
      names: ds0,ds1,ds2,ds3
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage_01?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root
      ds2:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage_02?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root
      ds3:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage_03?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root

    rules:
      sharding:
        tables:
          #配置逻辑数据库
          app_user:
            #数据库节点
            actual-data-nodes: ds$->{0..3}.app_user_$->{202401..202412}
            #分表策略
            table-strategy:
              standard:
                #分片键为 created_time  根据哪个字段分片,该字段叫分片键
                sharding-column: create_time
                #分表算法为
                sharding-algorithm-name: app-user-table-inline
            #分库策略
            database-strategy:
              standard:
                #分库列为id列
                sharding-column: id
                #分库算法 database_inline
                sharding-algorithm-name: app-user-database-inline

        #算法配置
        sharding-algorithms:
          #订单表分表算法
          app-user-table-inline:
            type: INTERVAL
            props:
              datetime-pattern: yyyy-MM-dd HH:mm:ss
              datetime-lower: 2024-01-01 00:00:00
              datetime-upper: 2024-12-01 00:00:00
              sharding-suffix-pattern: yyyyMM
              datetime-interval-unit: MONTHS
          #分库算法配置
          app-user-database-inline:
            type: INLINE
            props:
              algorithm-expression: ds$->{Math.abs(id.hashCode()%4)}

# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  # 设置别名包扫描路径,通过该属性可以给包中的类注册别名
  type-aliases-package: com.gzdemo.shardingdemo.pojo

3. 读写分离

使两个主库ds0,ds1负责写数据,因此把分库算法中取模4设置为取模2

ds0作为主库负责写,ds2负责读;ds1作为主库负责写,ds1和ds3负责读

配置

          #分库算法配置
          app-user-database-inline:
            type: INLINE
            props:
              algorithm-expression: ds$->{Math.abs(id.hashCode()%2)}
    rules:
      #读写分离配置
      readwrite-splitting:
        data-sources:
          ds0:
            #主数据源
            write-data-source-name: ds0
            #从数据源
            read-data-source-names: ds2
            #负载均衡算法
            load-balancer-name: random
          ds1:
            #主数据源
            write-data-source-name: ds1
            #从数据源
            read-data-source-names: ds1,ds3
            #负载均衡算法
            load-balancer-name: random
        #负载均衡算法
        load-balancers:
          round-robin:
            type: ROUND_ROBIN
          random:
            type: RANDOM

修改user_manage库(ds0)中的i第一个name为zhangsanmanage;
修改user_manage_01库(ds1)中的i第一个name为zhangsanmanage01;
修改user_manage_02库(ds2)中的i第一个name为zhangsan3manage02;
修改user_manage_03库(ds3)中的i第一个name为zhangsanmanage03;

在这里插入图片描述

测试list接口,发现每次请求id为11004的只有来自于ds02的数据;
而id为11001的由于采用random算法,有时候只有来自于ds03的数据,有时候ds01和ds03的都有;
当采用rr算法时,发现每次只有来自于ds03的数据。没有ds02的数据。
这里暂时还不清楚原因。
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4. 分库分表、读写分离所有配置

server:
  port: 8080

spring:
  shardingsphere:
    datasource:
      names: ds0,ds1,ds2,ds3
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage_01?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root
      ds2:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage_02?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root
      ds3:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.200.131:3306/user_manage_03?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
        username: root
        password: root

    rules:
      sharding:
        tables:
          #配置逻辑数据库
          app_user:
            #数据库节点
            actual-data-nodes: ds$->{0..3}.app_user_$->{202401..202412}
            #分表策略
            table-strategy:
              standard:
                #分片键为 created_time  根据哪个字段分片,该字段叫分片键
                sharding-column: create_time
                #分表算法为
                sharding-algorithm-name: app-user-table-inline
            #分库策略
            database-strategy:
              standard:
                #分库列为id列
                sharding-column: id
                #分库算法 database_inline
                sharding-algorithm-name: app-user-database-inline

        #算法配置
        sharding-algorithms:
          #订单表分表算法
          app-user-table-inline:
            type: INTERVAL
            props:
              datetime-pattern: yyyy-MM-dd HH:mm:ss
              datetime-lower: 2024-01-01 00:00:00
              datetime-upper: 2024-12-01 00:00:00
              sharding-suffix-pattern: yyyyMM
              datetime-interval-unit: MONTHS
          #分库算法配置
          app-user-database-inline:
            type: INLINE
            props:
              algorithm-expression: ds$->{Math.abs(id.hashCode()%2)}

      #读写分离配置
      readwrite-splitting:
        data-sources:
          ds0:
            #主数据源
            write-data-source-name: ds0
            #从数据源
            read-data-source-names: ds2
            #负载均衡算法
            load-balancer-name: random
          ds1:
            #主数据源
            write-data-source-name: ds1
            #从数据源
            read-data-source-names: ds1,ds3
            #负载均衡算法
            load-balancer-name: random
        #负载均衡算法
        load-balancers:
          round-robin:
            type: ROUND_ROBIN
          random:
            type: RANDOM


# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  # 设置别名包扫描路径,通过该属性可以给包中的类注册别名
  type-aliases-package: com.gzdemo.shardingdemo.pojo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值