上一篇文章我们主要搭建了一个分库分表的脚手架。里边集成了springboot框架,和mybats-plus以及相应表的增删改查。那么接下来我们就简单体验一下分库分表的实现。
我们采用最简单的 inline行内表达式策略,通过yml文件中几行简单的配置,来实现一个简单的分库操作。分库的策略是这样的,我们向订单表中插入10条数据,订单表中有订单id和用户id, 订单id我们采用雪花id的生成算法,用户id采用自增的方式,我们又两个库,ds0和ds1, 然后 userId%2, 匹配到不同库中,比如userId是1就保存到ds1库中,userId是2就保存到ds0库中,关于数据库结构,请参看上篇文章,已经给出了sql语句。两个库中都有一个order表。我们通过插入数据,观察效果。
首先我们创建一个项目module, sharding-inline-yml, (如果已经下载我上篇文章中的脚手架,这个模块已经建好了),依赖sharding-biz模块(该模块是mybatis-plus生成的增删改查), 接下来一步一步来。
一。 添加配置文件
首先添加一个application.yml
server:
port: 9991
spring:
profiles:
active: db
在添加一个配置文件 application-db.yml, (主要是为了后边再加一个application-table.yml演示分表)
# 分库
spring:
shardingsphere:
datasource: #数据源配置
names: ds0,ds1
ds0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
ds1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
sharding: #分片逻辑
default-database-strategy:
inline:
sharding-column: user_id
algorithm-expression: ds$->{user_id % 2}
binding-tables: t_order,t_order_item
broadcast-tables: t_user
tables: #表逻辑
t_order:
actual-data-nodes: ds$->{0..1}.t_order
key-generator:
column: order_id
type: SNOWFLAKE
props:
worker:
id: 10
t_order_item:
actual-data-nodes: ds$->{0..1}.t_order_item
key-generator:
column: order_item_id
type: SNOWFLAKE
props:
worker:
id: 12
添加Mybatis-plus配置类和启动主类,
接下来就可以测试了:
package cn.cestc.inline.controller;
import cn.cestc.biz.entity.Order;
import cn.cestc.biz.entity.User;
import cn.cestc.biz.service.AddressService;
import cn.cestc.biz.service.OrderItemService;
import cn.cestc.biz.service.OrderService;
import cn.cestc.biz.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
* @className: TestController
* @description:
* @author: sh.Liu
* @date: 2020-11-15 11:54
*/
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
private final UserService userService;
private final OrderService orderService;
private final OrderItemService orderItemService;
private final AddressService addressService;
public TestController(UserService userService, OrderService orderService, OrderItemService orderItemService, AddressService addressService) {
this.userService = userService;
this.orderService = orderService;
this.orderItemService = orderItemService;
this.addressService = addressService;
}
@RequestMapping("/user")
public String testUser(){
for (int i=1;i<=10; i++) {
User user = new User();
user.setUserId(Long.valueOf(i));
user.setUserName("张三" + i);
userService.save(user);
}
return "sucess";
}
@RequestMapping("/order")
public String testOrder(){
for (int i=1;i<=10; i++) {
Order order = new Order();
order.setUserId(Long.valueOf(i));
order.setOrderCode("acb"+ i);
order.setAddressId(String.valueOf(i));
orderService.save(order);
}
return "sucess";
}
@RequestMapping("/listOrder")
public Object testListOrder(){
List<Order> list = orderService.list(new LambdaQueryWrapper<Order>().in(Order::getUserId, Arrays.asList(1,2,3,4,5)).orderByAsc(Order::getUserId));
return list;
}
}
浏览器调用 localhost:9991/test/order, 查看Order表,发现
就这样数据就根据userId的值分散到了不同的库中。
那么这个规则是如何生效的呢,其实先秒尽在配置文件当中:
最关键的就是图上的三个红框。
首先配置两个数据源,ds0,ds1,
然后配置的是分库策略: 分片列是 user_id, 就是根据这列数据做分片, 算法表达式:
ds$->{user_id % 2} ,这个应该比较好理解,根据user_id 对2取余结果,计算存入到那个库中,
t_order表的真实表,
ds$->{0..1}.t_order。
存储没问题了之后,也可以测试一下查询,通过查询列表看得到的结果。 要注意,只支持 = 和 in
好了,本篇文章就分享到这里。下一篇我们介绍分表。