花了2天时间研究了一下Sharding-JDBC的使用,这里简单记录一下。
代码弄的比较乱,就没放到git上,需要源码的可以留下邮箱或者其他联系方式,我看到了发你。
遗留问题:Druid无法监控2个数据源的sql。
应该需要通过编写DataSourceConfig.java的方式解决。
目录
1.POM文件的内容
2.分库分表+分库不分表
3.读写分离
4.ComplexKeysShardingAlgorithm实现
1.POM文件的内容
pom文件在引用Sharding-jdbc时有2张方式:
sharding-jdbc-spring-boot-starter(后面的描述用的是这种方式)
这种方式可以不用自己写DataSourceConfig文件-
sharding-jdbc-core
这种方式的例子,基本都是要自己写DataSourceConfig文件的
参考:https://www.jianshu.com/p/3b2ab87b0de7
https://blog.csdn.net/a992795427/article/details/85102918
https://www.cnblogs.com/mr-yang-localhost/p/8280500.html#sharding-jdbc-spring-boot-starter方式的参考pom文件
org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.0 mysql mysql-connector-java 5.1.21 io.shardingsphere sharding-jdbc-spring-boot-starter 3.1.0.M1 com.alibaba druid-spring-boot-starter 1.1.23
2.分库分表+分库不分表
用的的数据库# 相关表结构
CREATE TABLE `order0` (
`id` bigint(11) NOT NULL COMMENT '主键ID',
`user_id` bigint(11) DEFAULT NULL COMMENT '用户ID',
`order_id` bigint(11) DEFAULT NULL COMMENT '订单ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_info` (
`user_id` bigint(19) NOT NULL,
`user_name` varchar(45) DEFAULT NULL,
`account` varchar(45) NOT NULL,
`password` varchar(45) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
application.properties文件参考
spring.application.name=sharding-jdbc
#mybatis
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.type-aliases-package=com.lbc.demo.model
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
#当注册遇到相同名字是否允许被注册,在配置中心无效
spring.main.allow-bean-definition-overriding=true
#所有主从库
sharding.jdbc.datasource.names=user0,user1
#dsmaster0
sharding.jdbc.datasource.user0.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.user0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.user0.url=jdbc:mysql://localhost:3306/user0?useSSL=false
sharding.jdbc.datasource.user0.username=root
sharding.jdbc.datasource.user0.password=password
#slave for ds_master_0
sharding.jdbc.datasource.user1.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.user1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.user1.url=jdbc:mysql://localhost:3306/user1?useSSL=false
sharding.jdbc.datasource.user1.username=root
sharding.jdbc.datasource.user1.password=password
#分库规则
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=user_id
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=user$->{user_id % 2}
# 绑定逻辑表
sharding.jdbc.config.sharding.binding-tables=order
# 设置分表规则
# sharding.jdbc.config.sharding.tables.逻辑表.actual-data-nodes:逻辑表对应的真实表
# sharding.jdbc.config.sharding.tables.逻辑表.table-strategy.inline.sharding-column:分表列
# sharding.jdbc.config.sharding.tables.逻辑表.table-strategy.inline.algorithm-expression:分表算法
# sharding.jdbc.config.sharding.tables.逻辑表.key-generator-column-name:主键列
# 分库,也分表
sharding.jdbc.config.sharding.tables.order.actual-data-nodes=user$->{0..1}.order$->{0..1}
sharding.jdbc.config.sharding.tables.order.table-strategy.inline.sharding-column=order_id
sharding.jdbc.config.sharding.tables.order.table-strategy.inline.algorithm-expression=order$->{order_id % 2}
sharding.jdbc.config.sharding.tables.order.key-generator-column-name=id
# 只分库,不分表
sharding.jdbc.config.sharding.tables.user_info.actual-data-nodes=user$->{0..1}.user_info
sharding.jdbc.config.sharding.tables.user_info.table-strategy.inline.sharding-column=user_id
sharding.jdbc.config.sharding.tables.user_info.table-strategy.inline.algorithm-expression=user_info
sharding.jdbc.config.sharding.tables.user_info.key-generator-column-name = user_id
#逻辑主从库名和实际主从库映射关系
#sharding.jdbc.config.sharding.master-slave-rules.ds0.master-data-source-name=dsmaster0
#用逗号分隔
#sharding.jdbc.config.sharding.master-slave-rules.ds0.slave-data-source-names=dsmaster0
#sharding.jdbc.config.sharding.master-slave-rules.dsmaster1.masterDataSourceName=dsmaster1
#sharding.jdbc.config.sharding.master-slave-rules.dsmaster1.slaveDataSourceNames=dsmaster1slave0
server.port=8080
3.读写分离
用到的数据库和表机构同上
application.yml参考文件
sharding:
jdbc:
dataSource:
names: db-test0,db-test1
# 配置主库
db-test0: #org.apache.tomcat.jdbc.pool.DataSource
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/user0?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: password
#最大连接数
maxPoolSize: 3
db-test1: # 配置第一个从库
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/user1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT
username: root
password: password
maxPoolSize: 3
config:
masterslave: # 配置读写分离
load-balance-algorithm-type: round_robin # 配置从库选择策略,提供轮询与随机,这里选择用轮询//random 随机 //round_robin 轮询
name: db1s2
master-data-source-name: db-test0
slave-data-source-names: db-test1
props:
sql: # 开启SQL显示,默认值: false,注意:仅配置读写分离时不会打印日志!!!
show: true
mybatis:
configuration:
map-underscore-to-camel-case: true
type-aliases-package: com.lbc.demo.model
mapper-locations: classpath:mapper/*Mapper.xml
4.ComplexKeysShardingAlgorithm实现
Complex方式的配置文件和2.分库分表+分库不分表的配置文件类似,只改了一个东西
分库,也分表
sharding.jdbc.config.sharding.tables.order.actual-data-nodes=user$->{0..1}.order$->{0..1}
sharding.jdbc.config.sharding.tables.order.table-strategy.complex.sharding-columns=user_id,order_id
sharding.jdbc.config.sharding.tables.order.table-strategy.complex.algorithm-class-name=com.lbc.demo.config.ComplexShardingAlgorithm
然后,需要增加一个路由类ComplexShardingAlgorithm,这里最好debug一下。
public class ComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm {
/**
* @param collection 在加载配置文件时,会解析表分片规则。将结果存储到 collection中,doSharding()参数使用
* @param shardingValues SQL中对应的
* @return
*/
@Override
public Collection doSharding(Collection collection, Collection shardingValues) {
System.out.println("collection:" + collection + ",shardingValues:" + shardingValues);
Collection orderIdValues = getShardingValue(shardingValues, "order_id");
Collection userIdValues = getShardingValue(shardingValues, "user_id");
List shardingSuffix = new ArrayList<>();
// user_id,order_id分片键进行分表
for (Long userId : userIdValues) {
for (Long orderId : orderIdValues) {
String suffix = userId % 2 + "_" + orderId % 2;
//写死测试
suffix="0";
for (String s : collection) {
if (s.endsWith(suffix)) {
shardingSuffix.add(s);
}
}
}
}
return shardingSuffix;
}
private Collection getShardingValue(Collection shardingValues, final String key) {
Collection valueSet = new ArrayList<>();
Iterator iterator = shardingValues.iterator();
while (iterator.hasNext()) {
ShardingValue next = iterator.next();
if (next instanceof ListShardingValue) {
ListShardingValue value = (ListShardingValue) next;
// user_id,order_id分片键进行分表
if (value.getColumnName().equals(key)) {
return value.getValues();
}
}
}
return valueSet;
}
}
参考了太多了,记不清了:
https://www.jianshu.com/p/3b2ab87b0de7
https://www.jianshu.com/p/9eebfae039c9
https://segmentfault.com/a/1190000019906637
https://www.cnblogs.com/yixinjishu/p/10876071.html
https://www.cnblogs.com/mr-yang-localhost/p/8280500.html
[https://blog.csdn.net/hy245120020/article/details/85335446]
https://www.jianshu.com/p/e4f291052c83
(https://blog.csdn.net/hy245120020/article/details/85335446)
https://blog.csdn.net/forezp/article/details/94343671
https://blog.csdn.net/a992795427/article/details/85102918
https://www.cnblogs.com/mr-yang-localhost/p/8280500.html