有些业务需要进行水平分表的时候,通常使用sharding-jdbc进行,先熟悉下简单使用sharding-jdbc。
创建好数据库:
t_order1,t_order2 订单表水平分表,订单表含有字段 :order_id-订单id,price-价格 ,user_id-用户id,status-订单状态
环境搭建:
搭建springboot + mybatis 框架,这里就不具体说了,都是基础。引入 sharding jdbc 依赖包 sharding-jdbc-spring-boot-starter
<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.1</version> </dependency>
问题:这里用的是sharding-jdbc-spring-boot-starter,
需要注意的是,如果使用了druid的话,
此时druid
不能用spring-boot-starter
版本的,需要用正常的包,否则报错
Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
sharding-jdbc配置:
环境搭建好之后,接下来就应该进行配置了,在application.yml文件中进行配置。
# 基本配置
server:
port: 2001
spring:
application:
name: 01-shardingjdbc基础使用
shardingsphere:
# 1-shardingjdbc 数据源配置
datasource:
names: o1
o1:
username: root_admin
password: 1234Root
url: jdbc:mysql://rm-wz9vg64rg8d4q5mc48o.mysql.rds.aliyuncs.com:3306/shardingjdbcdemo?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false # 设置时区
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource # 指定数据源为druid,这样就不会使用Springboot默认的连接池Hikari
# 2-配置数据节点,绑定逻辑表和真实表的关系 逻辑表=t_order,真实表=t_order_1、t_order_2
sharding:
tables:
t_order:
actual-data-nodes: o1.t_order_$->{1..2}
table-strategy: # 3-分片策略配置,配置分片健 和 分片算法
inline:
sharding-column: order_id
algorithm-expression: t_order_$->{order_id % 2 + 1}
props:
sql:
show: true # 4-打开sql输出
- 1-sharding-jdbc数据源配置,数据源别名叫做o1,可以配置多个
- 2-配置数据节点,绑定逻辑表和真实表的关系 逻辑表=t_order,真实表=t_order_1、t_order_2
- 3-分片策略配置,配置分片健 和 分片算法
测试:
实现一个dao
import com.sharding.learing.entity.OrderEntity;
import tk.mybatis.mapper.common.Mapper;
public interface OrderDao extends Mapper<OrderEntity> {
}
测试:
@SpringBootTest
public class TestController {
@Resource
private OrderDao orderDao;
@Test
void insert() {
OrderEntity orderEntity = new OrderEntity();
orderEntity.setPkId((long) 1);
orderEntity.setOrderId((long) 1000001);
orderEntity.setUserId((long) 1111111);
orderEntity.setStatus(1);
orderDao.insert(orderEntity);
}
}
查看日志:
2021-04-07 10:27:40.447 INFO 990 --- [ main] ShardingSphere-SQL : Rule Type: sharding
2021-04-07 10:27:40.447 INFO 990 --- [ main] ShardingSphere-SQL : Logic SQL: INSERT INTO t_order ( pk_id,order_id,user_id,status ) VALUES( ?,?,?,? )
2021-04-07 10:27:40.447 INFO 990 --- [ main] ShardingSphere-SQL : SQLStatement: InsertSQLStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@33239d72, tablesContext=TablesContext(tables=[Table(name=t_order, alias=Optional.absent())], schema=Optional.absent())), columnNames=[pk_id, order_id, user_id, status], insertValueContexts=[InsertValueContext(parametersCount=4, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=63, stopIndex=63, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=65, stopIndex=65, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=2), ParameterMarkerExpressionSegment(startIndex=69, stopIndex=69, parameterMarkerIndex=3)], parameters=[2, 1000001, 1111111, 1])])
2021-04-07 10:27:40.447 INFO 990 --- [ main] ShardingSphere-SQL : Actual SQL: o1 ::: INSERT INTO t_order_2 ( pk_id,order_id,user_id,status ) VALUES(?, ?, ?, ?) ::: [2, 1000001, 1111111, 1]
执行流程简要分析:
通过日志分析,sharding-jdbc在拿到用户要执行的sql之后干了哪些事:
- 解析sql,获取分片健值,在本例子中就是order_id
- sharding-jdbc通过规则配置t_order_$->{order_id % 2 + 1},知道了当order_id为偶数时,应该往哪个表进行操作,这里就是通过我们配置的分片策略计算到的
- 然后sharding-jdbc根据order_id的值改写sql语句,改写后的sql语句就是要真实执行的sql语句
- 执行改写后的sql,并且进行汇总返回