坑
这里没有使用springboot-starter-druid的依赖,如果用这个,会和shardingJdbc冲突,解决办法就是在启动类上排除 @SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class})
先创建好数据库ds_0,ds_1
并分别在两个数据库中创建表news,order_info_0,order_info_1,order_item_0,order_item_1
其中 news表用于默认数据源配置的测试
order_info和order_item为分库分表和绑定表测试
CREATE TABLE `news` (
`title` varchar(50) DEFAULT NULL,
`hits` int(11) DEFAULT NULL,
`content` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `order_info_0` (
`oid` bigint(20) DEFAULT NULL,
`uid` int(11) DEFAULT NULL,
`status` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `order_item_0` (
`itemId` bigint(20) NOT NULL,
`uid` int(11) DEFAULT NULL,
`oid` bigint(20) DEFAULT NULL,
`status` varchar(50) DEFAULT NULL,
PRIMARY KEY (`itemId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
需求:根据uid,数据到ds_0或ds_1数据库,根据oid,数据到order_info_0或order_info_1表
1 新建springboot项目,添加依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- sharding-jdbc starter -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>3.0.0.M2</version>
</dependency>
2 编写分库分表的核心配置文件application.properties
# 数据库连接池配置变量
initialSize=5
minIdle=5
maxIdle=100
maxActive=20
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
# --------------- 配置真实的数据源 ---------------
# 真实数据源配置,这里的ds0,ds1会在下面的配置中引用
sharding.jdbc.datasource.names=ds0,ds1
# 数据库连接1
sharding.jdbc.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
# 坑,注意这里是key是url,如果使用默认数据源com.zaxxer.hikari.HikariDataSource,则是jdbc-url
sharding.jdbc.datasource.ds0.url=jdbc:mysql://localhost:3306/ds_0?useSSL=false&serverTimezone=GMT
sharding.jdbc.datasource.ds0.username=root
sharding.jdbc.datasource.ds0.password=123456
# 初始连接数
sharding.jdbc.datasource.ds0.initialSize=${initialSize}
# 最小连接数
sharding.jdbc.datasource.ds0.minIdle=${minIdle}
# 最大连接池数量
sharding.jdbc.datasource.ds0.maxActive=${maxActive}
# 配置获取连接等待超时的时间
sharding.jdbc.datasource.ds0.maxWait=${maxWait}
# 用来检测连接是否有效的sql
sharding.jdbc.datasource.ds0.validationQuery=SELECT 1 FROM DUAL
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
sharding.jdbc.datasource.ds0.timeBetweenEvictionRunsMillis=${timeBetweenEvictionRunsMillis}
# 配置一个连接在池中最小生存的时间,单位是毫秒
sharding.jdbc.datasource.ds0.minEvictableIdleTimeMillis=${minEvictableIdleTimeMillis}
# 数据库连接2
sharding.jdbc.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds1.url=jdbc:mysql://localhost:3306/ds_1?useSSL=false&serverTimezone=GMT
sharding.jdbc.datasource.ds1.username=root
sharding.jdbc.datasource.ds1.password=123456
# 初始连接数
sharding.jdbc.datasource.ds1.initialSize=${initialSize}
# 最小连接数
sharding.jdbc.datasource.ds1.minIdle=${minIdle}
# 最大连接池数量
sharding.jdbc.datasource.ds1.maxActive=${maxActive}
# 配置获取连接等待超时的时间
sharding.jdbc.datasource.ds1.maxWait=${maxWait}
# 用来检测连接是否有效的sql
sharding.jdbc.datasource.ds1.validationQuery=SELECT 1 FROM DUAL
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
sharding.jdbc.datasource.ds1.timeBetweenEvictionRunsMillis=${timeBetweenEvictionRunsMillis}
# 配置一个连接在池中最小生存的时间,单位是毫秒
sharding.jdbc.datasource.ds1.minEvictableIdleTimeMillis=${minEvictableIdleTimeMillis}
# --------------- 数据库的分片策略 ---------------
# 数据库的分片策略 根据uid,分成ds_0,ds_1两个数据库
# 分库列
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=uid
# 分库算法
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=ds$->{uid % 2}
# --------------- 表的的分片策略(可配置多个) ---------------
# 配置逻辑表order_info实际节点,这里的ds就是引用上面定义的名称
# 其中 sharding.tables.order_info是逻辑表,ds$->{0..1}.order_info是真实的表
sharding.jdbc.config.sharding.tables.order_info.actual-data-nodes=ds$->{0..1}.order_info_$->{0..1}
# 配置自动生成主键,生成分布式id,防止主键重复
sharding.jdbc.config.sharding.tables.order_info.key-generator-column-name=oid
# 表的分片策略根据 oid,分成order_info_0,order_info_1两个表
# 指定表分片的列,表示我们是使用哪个列进行分片
sharding.jdbc.config.sharding.tables.order_info.table-strategy.inline.sharding-column=oid
# 表分片 算法表达式
# ----------- 这里不能跟分库策略一样,否则会导致有一半数据表没有机会插入数据 -----------
sharding.jdbc.config.sharding.tables.order_info.table-strategy.inline.algorithm-expression=order_info_${(oid % 5) % 2}
# 配置生成自增ID的雪花算法,单台服务器可以不配置
spring.shardingsphere.sharding.tables.order_info.key-generator.column=oid
# 使用snowflake算法
spring.shardingsphere.sharding.tables.order_info.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.order_info.key-generator.props.worker.id=1
spring.shardingsphere.sharding.tables.order_info.key-generator.props.max.tolerate.time.difference.milliseconds=0
# 定义逻辑表order_item的真实数据节点,生成分布式主键id,分表列,分表的规则
sharding.jdbc.config.sharding.tables.order_item.actual-data-nodes=ds$->{0..1}.order_item_$->{0..1}
sharding.jdbc.config.sharding.tables.order_item.key-generator-column-name=itemId
sharding.jdbc.config.sharding.tables.order_item.table-strategy.inline.sharding-column=oid
sharding.jdbc.config.sharding.tables.order_item.table-strategy.inline.algorithm-expression=order_item_${(oid % 5) % 2}
# 绑定表,效率高,避免出现笛卡尔
# 有文章说主表和子表的分片规则一样的时候,绑定表生效,测试时两个表可以不一样,也会生效
sharding.jdbc.config.sharding.binding-tables[0]= order_info,order_item
# 未配置分片规则的表将通过默认数据源定位
# 有些情况下,我们某些表并不需要进行分表分库,所以需要这样设置
sharding.jdbc.config.sharding.default-data-source-name=ds1
# 显示运行的sql
sharding.jdbc.config.sharding.props.sql.show=true
3 剩下的按照正常的流程开发,唯一需要注意的,mapper层所操作的表,都是逻辑表
测试时,可观察到控制台输出的真实sql
springboot整合mybatis可参考博文 springboot 整合mybatis和druid数据源连接池_mybaitis druid单数据源 获取连接-CSDN博客