官方文档:https://shardingsphere.apache.org/document/current/cn/overview/
学习视频:https://www.bilibili.com/video/BV1LK411s7RX?p=2&vd_source=fc7fa697b97f292319c5b0cde4755484
代码:https://gitee.com/wangzai6/sharding-jdbc.git
把操作数据库某张表,把这张表中一部分字段数据存到一张新表里面,再把这张表另一部分字段数据存到另外一张表里面
pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.2.1.RELEASE
com.hejiawang
sharding
0.0.1-SNAPSHOT
sharding
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
com.alibaba
druid-spring-boot-starter
1.1.20
mysql
mysql-connector-java
org.apache.shardingsphere
sharding-jdbc-spring-boot-starter
4.0.0-RC1
com.baomidou
mybatis-plus-boot-starter
3.0.5
org.projectlombok
lombok
org.springframework.boot
spring-boot-maven-plugin
create table course_1(
cid bigint(20) PRIMARY KEY ,
cname varchar(50) not null ,
user_id bigint(20) not null ,
cstatus varchar(10) not null
)
create table course_2(
cid bigint(20) PRIMARY KEY ,
cname varchar(50) not null ,
user_id bigint(20) not null ,
cstatus varchar(10) not null
)
Course
package com.hejiawang.sharding.entity;
import lombok.Data;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-13 16:34
**/
@Data
public class Course {
private Long cid;
private String cname;
private Long userId;
private String cstatus;
}
CourseMapper
package com.hejiawang.sharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hejiawang.sharding.entity.Course;
import org.springframework.stereotype.Repository;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-13 16:35
**/
@Repository
public interface CourseMapper extends BaseMapper<Course> {
}
ShardingApplication
package com.hejiawang.sharding;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.hejiawang.sharding.mapper")
public class ShardingApplication {
public static void main(String[] args) {
SpringApplication.run(ShardingApplication.class, args);
}
}
application.properties
# shardingjdbc分片策略
#配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=ds1
#一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true
# 配置数据源具体内容,包含连接池,驱动地址,用户名和密码
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://ip:端口/course_db?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds1.username = xxx
spring.shardingsphere.datasource.ds1.password = xxx
#指定course表分布情况,配置表在哪个数据库里面,表名称都是什么 ds1.course_1 ds1.course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=ds1.course_$->{1..2}
# 指定course表里面主键cid生成策略 snowflake
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=snowflake
# 指定分片策略 约定cid值偶数添加到course_1表,如果cid是奇数添加到course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1}
#打开sql输出日志
spring.shardingsphere.props.sql.show=true
测试类 ShardingApplicationTests
package com.hejiawang.sharding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hejiawang.sharding.entity.Course;
import com.hejiawang.sharding.mapper.CourseMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingApplicationTests {
// 注入mapper
@Autowired
private CourseMapper courseeMapper;
// 添加课程
@Test
public void addCourse(){
for (int i = 0 ; i <=10 ; i++){
Course course = new Course();
course.setCname("java");
course.setUserId(100L);
course.setCstatus("Normal"+i);
courseeMapper.insert(course);
}
}
// 查询课程方法
@Test
public void findCourse(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("cid",754034712887951360L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
}
调用测试添加方法
cid通过雪花算法生成,如果为奇数则插入course_2,偶数则插入course_1
打印日志
create table course_1(
cid bigint(20) PRIMARY KEY ,
cname varchar(50) not null ,
user_id bigint(20) not null ,
cstatus varchar(10) not null
)
create table course_2(
cid bigint(20) PRIMARY KEY ,
cname varchar(50) not null ,
user_id bigint(20) not null ,
cstatus varchar(10) not null
)
application.properties
# shardingjdbc分片策略
#配置数据源,给数据源起名称,水平分库
spring.shardingsphere.datasource.names=ds1,ds2
#一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true
# 配置第一个数据源具体内容,包含连接池,驱动地址,用户名和密码
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://ip:端口/edu_db_1?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds1.username = xxx
spring.shardingsphere.datasource.ds1.password = xxx
# 配置第二个数据源具体内容,包含连接池,驱动地址,用户名和密码
spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds2.url=jdbc:mysql://ip:端口/edu_db_2?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds2.username = xxx
spring.shardingsphere.datasource.ds2.password = xxx
#指定数据库分布情况,数据库里面表分布情况
# ds1 ds2 course_1 course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=ds$->{1..2}.course_$->{1..2}
# 指定course表里面主键cid生成策略 snowflake
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=snowflake
# 指定表分片策略 约定cid值偶数添加到course_1表,如果cid是奇数添加到course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1}
# 指定数据库分片策略 约定user_id是偶数添加ds1,是奇数添加ds2
# 数据库中所有表的规则
# spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
# spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{userid % 2 + 1}
# 指定到具体表的库规则
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=ds$->{user_id % 2 + 1}
#打开sql输出日志
spring.shardingsphere.props.sql.show=true
package com.hejiawang.sharding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hejiawang.sharding.entity.Course;
import com.hejiawang.sharding.mapper.CourseMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingApplicationTests {
// 注入mapper
@Autowired
private CourseMapper courseeMapper;
// ===============测试水平分库=================
@Test
public void addCourseDb(){
Course course = new Course();
course.setCname("C++");
// 分库根据user_id
course.setUserId(100L);
course.setCstatus("Normal");
courseeMapper.insert(course);
}
@Test
public void findCourseDb(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("user_id",100L);
wrapper.eq("cid",754375827029753857L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
// ===============测试水平分表=================
// 添加课程
@Test
public void addCourse(){
for (int i = 0 ; i <=10 ; i++){
Course course = new Course();
course.setCname("C语言");
course.setUserId(100L);
course.setCstatus("Normal"+i);
courseeMapper.insert(course);
}
}
// 查询课程方法
@Test
public void findCourse(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("cid",754034712887951360L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
}
执行水平分库方法addCourseDb(),查看打印结果
数据库为ds1配置的数据源edu_db_1 下的course_2
查询方法,当只写userid的时候,打印2条sql course_1和course_2都查询了
查询方法,写userid和cid的时候,打印1条sql,直接查询到了
create table t_user(
user_id bigint(20) not null ,
username varchar(100) not null,
ustatus varchar(50) not null
)
注意 User实体类要映射到表名t_user,否则会报错
User
package com.hejiawang.sharding.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-14 16:33
**/
@Data
@TableName(value = "t_user") //指定对应表
public class User {
private Long userId;
private String username;
private String ustatus;
}
UserMapper
package com.hejiawang.sharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hejiawang.sharding.entity.User;
import org.springframework.stereotype.Repository;
@Repository
public interface UserMapper extends BaseMapper<User> {
}
配置规则application.properties
# shardingjdbc分片策略
#配置数据源,给数据源起名称,水平分库
spring.shardingsphere.datasource.names=ds1,ds2,ds3
#一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true
# 配置第一个数据源具体内容,包含连接池,驱动地址,用户名和密码
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://ip:端口/edu_db_1?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds1.username = xxx
spring.shardingsphere.datasource.ds1.password = xxx
# 配置第二个数据源具体内容,包含连接池,驱动地址,用户名和密码
spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds2.url=jdbc:mysql://ip:端口/edu_db_2?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds2.username = xxx
spring.shardingsphere.datasource.ds2.password = xxx
# 配置第三个数据源具体内容,包含连接池,驱动地址,用户名和密码
spring.shardingsphere.datasource.ds3.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds3.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds3.url=jdbc:mysql://ip:端口/user_db?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds3.username = xxx
spring.shardingsphere.datasource.ds3.password = xxx
# 配置user_db数据库里面t_user 专库专表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ds$->{3}.t_user
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=snowflake
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user
#指定数据库分布情况,数据库里面表分布情况
# ds1 ds2 course_1 course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=ds$->{1..2}.course_$->{1..2}
# 指定course表里面主键cid生成策略 snowflake
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=snowflake
# 指定表分片策略 约定cid值偶数添加到course_1表,如果cid是奇数添加到course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1}
# 指定数据库分片策略 约定user_id是偶数添加ds1,是奇数添加ds2
# 数据库中所有表的规则
# spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
# spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{userid % 2 + 1}
# 指定到具体表的库规则
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=ds$->{user_id % 2 + 1}
#打开sql输出日志
spring.shardingsphere.props.sql.show=true
测试类
package com.hejiawang.sharding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hejiawang.sharding.entity.Course;
import com.hejiawang.sharding.entity.User;
import com.hejiawang.sharding.mapper.CourseMapper;
import com.hejiawang.sharding.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingApplicationTests {
// 注入mapper
@Autowired
private CourseMapper courseeMapper;
@Autowired
private UserMapper userMapper;
// ===============测试垂直分库=================
@Test
public void addUserDb(){
User user = new User();
user.setUsername("飞哥");
user.setUstatus("牛逼");
userMapper.insert(user);
}
@Test
public void findUserDb(){
QueryWrapper<User> wrapper = new QueryWrapper();
wrapper.eq("user_id",754388854030467073L);
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
// ===============测试水平分库=================
@Test
public void addCourseDb(){
Course course = new Course();
course.setCname("C++");
// 分库根据user_id
course.setUserId(100L);
course.setCstatus("Normal");
courseeMapper.insert(course);
}
@Test
public void findCourseDb(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("user_id",100L);
wrapper.eq("cid",754375827029753857L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
// ===============测试水平分表=================
// 添加课程
@Test
public void addCourse(){
for (int i = 0 ; i <=10 ; i++){
Course course = new Course();
course.setCname("C语言");
course.setUserId(100L);
course.setCstatus("Normal"+i);
courseeMapper.insert(course);
}
}
// 查询课程方法
@Test
public void findCourse(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("cid",754034712887951360L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
}
运行addUserDb()方法,走ds3数据源
运行findUserDb()方法,走ds3数据源
存储固定数据的表,表数据很少发生变化,查询时经常要关联的表
在每个数据库中创建相同结构公共表
在edu_db_1,edu_db_2,user_db中创建公共表
create table t_udict(
dictid bigint(20) primary key ,
ustatus varchar(100) not null ,
uvalue varchar(100) not null
)
application.properties
# 配置公共表
spring.shardingsphere.sharding.broadcast-tables=t_udict
spring.shardingsphere.sharding.tables.t_udict.key-generator.type=snowflake
spring.shardingsphere.sharding.tables.t_udict.key-generator.column=dictid
1.创建新实体类和mapper
Udict
package com.hejiawang.sharding.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-14 20:54
**/
@Data
@TableName(value = "t_udict")
public class Udict {
private Long dictid;
private String ustatus;
private String uvalue;
}
UdictMapper
package com.hejiawang.sharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hejiawang.sharding.entity.Udict;
import org.springframework.stereotype.Repository;
@Repository
public interface UdictMapper extends BaseMapper<Udict> {
}
测试类
package com.hejiawang.sharding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hejiawang.sharding.entity.Course;
import com.hejiawang.sharding.entity.Udict;
import com.hejiawang.sharding.entity.User;
import com.hejiawang.sharding.mapper.CourseMapper;
import com.hejiawang.sharding.mapper.UdictMapper;
import com.hejiawang.sharding.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingApplicationTests {
// 注入mapper
@Autowired
private CourseMapper courseeMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private UdictMapper udictMapper;
// ===============测试公共表=================
@Test
public void addDict(){
Udict udict = new Udict();
udict.setUstatus("状态非常好");
udict.setUvalue("已启用");
udictMapper.insert(udict);
}
@Test
public void deleteDict(){
QueryWrapper<Udict> wrapper = new QueryWrapper<>();
wrapper.eq("dictid",754449834907271169L);
udictMapper.delete(wrapper);
}
// ===============测试垂直分库=================
@Test
public void addUserDb(){
User user = new User();
user.setUsername("飞哥");
user.setUstatus("牛逼");
userMapper.insert(user);
}
@Test
public void findUserDb(){
QueryWrapper<User> wrapper = new QueryWrapper();
wrapper.eq("user_id",754389540776443905L);
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
// ===============测试水平分库=================
@Test
public void addCourseDb(){
Course course = new Course();
course.setCname("C++");
// 分库根据user_id
course.setUserId(100L);
course.setCstatus("Normal");
courseeMapper.insert(course);
}
@Test
public void findCourseDb(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("user_id",100L);
wrapper.eq("cid",754375827029753857L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
// ===============测试水平分表=================
// 添加课程
@Test
public void addCourse(){
for (int i = 0 ; i <=10 ; i++){
Course course = new Course();
course.setCname("C语言");
course.setUserId(100L);
course.setCstatus("Normal"+i);
courseeMapper.insert(course);
}
}
// 查询课程方法
@Test
public void findCourse(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("cid",754034712887951360L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
}
调用addDict()方法,所有配置数据源下的t_udict表都插入了相同的数据
调用deleteDict()方法,生成3条删除sql,所有数据源中的表数据都删除了
sharding-jdbc通过对sql语句语义分析,实现读写分离过程,不会做数据库同步
参考前面文章
https://blog.csdn.net/Persistence___/article/details/123215121?spm=1001.2014.3001.5501
User
package com.hejiawang.sharding.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-14 16:33
**/
@Data
@TableName(value = "t_user") //指定对应表
public class User {
private Long userId;
private String username;
private String ustatus;
}
UserMapper
package com.hejiawang.sharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hejiawang.sharding.entity.User;
import org.springframework.stereotype.Repository;
@Repository
public interface UserMapper extends BaseMapper<User> {
}
application配置
# shardingjdbc分片策略
#配置数据源,给数据源起名称,水平分库
spring.shardingsphere.datasource.names=ds3,s3
#一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true
# 配置第三个数据源具体内容,包含连接池,驱动地址,用户名和密码
# user_db主服务器
spring.shardingsphere.datasource.ds3.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds3.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds3.url=jdbc:mysql://ip:端口/user_db?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds3.username = xxx
spring.shardingsphere.datasource.ds3.password = xxx
# user_db从服务器
spring.shardingsphere.datasource.s3.type=com.alibaba.druid.pool.DruidDataSource
#jdk1.8 com.mysql.cj.jdbc.Driver
#jdk1.8以下 om.mysql.jdbc.Driver
spring.shardingsphere.datasource.s3.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.s3.url=jdbc:mysql://ip:端口/user_db?serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.s3.username = xxx
spring.shardingsphere.datasource.s3.password = xxx
# 主库从库逻辑数据源定义 ds3为user_db
spring.shardingsphere.sharding.master-slave-rules.ms3.master-data-source-name=ds3
spring.shardingsphere.sharding.master-slave-rules.ms3.slave-data-source-names=s3
# 配置user_db数据库里面t_user 专库专表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ms3.t_user
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=snowflake
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user
#打开sql输出日志
spring.shardingsphere.props.sql.show=true
测试类
package com.hejiawang.sharding;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hejiawang.sharding.entity.Course;
import com.hejiawang.sharding.entity.Udict;
import com.hejiawang.sharding.entity.User;
import com.hejiawang.sharding.mapper.CourseMapper;
import com.hejiawang.sharding.mapper.UdictMapper;
import com.hejiawang.sharding.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingApplicationTests {
// 注入mapper
@Autowired
private CourseMapper courseeMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private UdictMapper udictMapper;
// ===============测试读写分离=================
@Test
public void addUserDbMaster(){
User user = new User();
user.setUsername("肥宅子");
user.setUstatus("牛逼!!!");
userMapper.insert(user);
}
@Test
public void findUserDbSlave(){
QueryWrapper<User> wrapper = new QueryWrapper();
wrapper.eq("user_id",754389540776443905L);
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
// ===============测试公共表=================
@Test
public void addDict(){
Udict udict = new Udict();
udict.setUstatus("状态非常好");
udict.setUvalue("已启用");
udictMapper.insert(udict);
}
@Test
public void deleteDict(){
QueryWrapper<Udict> wrapper = new QueryWrapper<>();
wrapper.eq("dictid",754449834907271169L);
udictMapper.delete(wrapper);
}
// ===============测试垂直分库=================
@Test
public void addUserDb(){
User user = new User();
user.setUsername("飞哥");
user.setUstatus("牛逼");
userMapper.insert(user);
}
@Test
public void findUserDb(){
QueryWrapper<User> wrapper = new QueryWrapper();
wrapper.eq("user_id",754389540776443905L);
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
// ===============测试水平分库=================
@Test
public void addCourseDb(){
Course course = new Course();
course.setCname("C++");
// 分库根据user_id
course.setUserId(100L);
course.setCstatus("Normal");
courseeMapper.insert(course);
}
@Test
public void findCourseDb(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("user_id",100L);
wrapper.eq("cid",754375827029753857L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
// ===============测试水平分表=================
// 添加课程
@Test
public void addCourse(){
for (int i = 0 ; i <=10 ; i++){
Course course = new Course();
course.setCname("C语言");
course.setUserId(100L);
course.setCstatus("Normal"+i);
courseeMapper.insert(course);
}
}
// 查询课程方法
@Test
public void findCourse(){
QueryWrapper<Course> wrapper = new QueryWrapper();
// wrapper.eq("cid",754034711998758913L);
wrapper.eq("cid",754034712887951360L);
Course course = courseeMapper.selectOne(wrapper);
System.out.println(course);
}
}
调用addUserDbMaster()方法,insert方法走的ds3数据源,ds3为主库
调用findUserDbSlave()方法,select方法走的s3数据源,s3为从库