当项目开始的时候,没有想到后续的分库分表的话,其实对于后续的分库分表操作多少会有一些较难处理的,所以一般分库分表都是在开始的时候就提前已经规划了,已经预留了口子,之后才能顺利的进行;
其实也不是必须要分库分表,由于国产高性能数据库等的出现,例如 tidb,完全遵守sql92标准,其实直接换上这个也是个非常不错的选择;
所以这就是我的springboot项目,引入了mp,然后可以实现单表的增删改查
org.apache.shardingsphere
sharding-jdbc-spring-boot-starter
4.1.1
# 水平单库分表配置
spring:
main:
allow-bean-definition-overriding: true
sharding-sphere:
datasource:
m1:
driver-class-name: com.mysql.cj.jdbc.Driver
password: root
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/coursedb?serverTimezone=GMT%2B8
username: root
names: m1
props:
sql:
show: true
sharding:
tables:
course:
actual-data-nodes: m1.course_$->{1..2}
key-generator:
column: cid
type: SNOWFLAKE
table-strategy:
inline:
algorithm-expression: course_$->{cid%2+1}
sharding-column: cid
我现在相当于之前的代码没有任何改动
然后yml更改为了shardingjdbc 分库分表配置
我将要应用的表为 coursedb 库中的 course_1 和 course_2
至此,sardingjdbc已经这个完毕了! 就是这么简单,直接看效果
@SpringBootTest
@RunWith(SpringRunner.class)
class DemoShardingJdbcApplicationTests {
@Resource
CourseMapper courseMapper;
/**
* 插入多条,分配到不同的表中
*/
@Test
void insert() {
for (int i = 0; i < 10; i++) {
Course record = new Course();
record.setCname("java" + i);
record.setCstatus("1");
record.setUserId(RandomUtil.randomLong(50));
System.out.println(courseMapper.insert(record));
}
}
}
ShardingSphere-SQL: Logic SQL: INSERT INTO course ( cid,
cname,
user_id,
cstatus ) VALUES ( ?,
?,
?,
? )
ShardingSphere-SQL: Actual SQL: m1 ::: INSERT INTO course_2 ( cid,
cname,
user_id,
cstatus ) VALUES (?, ?, ?, ?) ::: [1646822909442260993, java9, 9, 1]
原始sql Logic SQL: INSERT INTO course
实际执行的sql Actual SQL: m1 ::: INSERT INTO course_2
没错,之前的表名称不用动,但是实际上已经在用 course_1 和 course_2
# 水平分库 表不再分配置
spring:
main:
allow-bean-definition-overriding: true
sharding-sphere:
datasource:
m1:
driver-class-name: com.mysql.cj.jdbc.Driver
password: root
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/coursedb0?serverTimezone=GMT%2B8
username: root
m2:
driver-class-name: com.mysql.cj.jdbc.Driver
password: root
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/coursedb1?serverTimezone=GMT%2B8
username: root
names: m1,m2
props:
sql:
show: true
sharding:
tables:
course:
actual-data-nodes: m$->{1..2}.course
key-generator:
column: cid
type: SNOWFLAKE
table-strategy:
inline:
algorithm-expression: course
sharding-column: cid
# 水平分库 分表配置
spring:
main:
allow-bean-definition-overriding: true
sharding-sphere:
datasource:
m1:
driver-class-name: com.mysql.cj.jdbc.Driver
password: root
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/coursedb0?serverTimezone=GMT%2B8
username: root
m2:
driver-class-name: com.mysql.cj.jdbc.Driver
password: root
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/coursedb1?serverTimezone=GMT%2B8
username: root
names: m1,m2
props:
sql:
show: true
sharding:
# 所有不分片的表,默认执行库
default-data-source-name: m1
tables:
course:
actual-data-nodes: m$->{1..2}.course_$->{1..2}
key-generator:
column: cid
type: SNOWFLAKE
database-strategy:
inline:
algorithm-expression: m$->{user_id % 2 +1}
# 配置数据库字段 不是实体类中的字段
sharding-column: user_id
table-strategy:
inline:
algorithm-expression: course_$->{cid % 2 +1}
sharding-column: cid
tables:
course:
actual-data-nodes: m$->{1..2}.course_$->{1..2}
key-generator:
column: cid
type: SNOWFLAKE
database-strategy:
inline:
algorithm-expression: m$->{user_id % 2 +1}
# 配置数据库字段 不是实体类中的字段
sharding-column: user_id
table-strategy:
inline:
algorithm-expression: course_$->{cid % 2 +1}
sharding-column: cid
- mKaTeX parse error: Expected group after '_' at position 16: ->{1..2}.course_̲->{1…2} 代表笛卡尔乘积,相当于m1.course_1,m1.course_2,m2.course_1,m2.course_2
- database-strategy 分库策略: 选择 m1 / m2
- user_id 分库策略具体算法字段,具体算法 m$->{user_id % 2 +1}
- table-strategy 分表策略: 选择 course_1 / course_2
- cid 分表策略具体算法字段,具体算法 course_$->{cid % 2 +1}
当 user_id 为偶数, cid 为偶数, 选择的应该是 m1.course_1
当 user_id 为偶数, cid 为奇数, 选择的应该是 m1.course_2
当 user_id 为奇数, cid 为偶数, 选择的应该是 m2.course_1
当 user_id 为奇数, cid 为奇数, 选择的应该是 m2.course_2
所有代码均在gitee上: 项目地址
后续还有分页,排序,分布式事务等