首先说一下sharding-jdbc和mycat吧
相同点:都可以做数据库读写分离,分片。
不同点:前者为轻量级,是在代码层进行操作;后者为重量级,相当于一个中间件;
先说下大致流程:把t_order表拆分成t_order_0与t_order_1,里面只有user_id和order_id两个字段。
然后通过集成,用mybatis-plus自带的插入,查询,去操作两个表数据。这是水平分库的一个demo
直接开始操作,下面是我引入的所有依赖,可能存在多余项目,可以看情况自己集成。
<dependencies>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>3.0.0.M3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--集成mybatis -->
<!-- 与数据库操作相关的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 使用数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- mybatisplus集成 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.1.8</version>
</dependency>
</dependencies>
entity层:
是用mybatis-plus的代码生成器生成出来的,这里需要注意一下@TableName("t_order"),这里写的这个表是虚拟表,
到时候会对应到yml文件里,可以记录一下,自己去配置文件里对比。
package com.zyx.entity;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableName;
/**
* <p>
*
* </p>
*
* @author zyx
* @since 2019-10-22
*/
@TableName("t_order")
public class TOrder0 implements Serializable {
private static final long serialVersionUID = 1L;
@TableField("order_id")
private Long orderId;
@TableField("user_id")
private Long userId;
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
@Override
public String toString() {
return "TOrder0{" +
", orderId=" + orderId +
", userId=" + userId +
"}";
}
}
接下来是service,这些都是用生成器生成的。所以出现了TOrder0这种名字,可以自行去优化一下。
package com.zyx.service;
import com.zyx.entity.TOrder0;
import com.baomidou.mybatisplus.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author zyx
* @since 2019-10-22
*/
public interface TOrder0Service extends IService<TOrder0> {
}
然后是impl实现类
package com.zyx.service.impl;
import com.zyx.entity.TOrder0;
import com.zyx.mapper.TOrder0Mapper;
import com.zyx.service.TOrder0Service;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author zyx
* @since 2019-10-22
*/
@Service
public class TOrder0ServiceImpl extends ServiceImpl<TOrder0Mapper, TOrder0> implements TOrder0Service {
}
mapper:
package com.zyx.mapper;
import com.zyx.entity.TOrder0;
import com.baomidou.mybatisplus.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author zyx
* @since 2019-10-22
*/
public interface TOrder0Mapper extends BaseMapper<TOrder0> {
}
mapper的xml我就不贴了,反正没用到,但是自己去建的时候要记得创建一下,到时候扫包会用到,如果没有的话要报错的。
然后建立一个controller来测试一下:
package com.zyx.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zyx.entity.TOrder0;
import com.zyx.service.TOrder0Service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
/**
* <p>
* 前端控制器
* </p>
*
* @author zyx
* @since 2019-10-22
*/
@RestController
@RequestMapping("/tOrder")
public class TOrder0Controller {
@Autowired
private TOrder0Service tOrder0Service;
@GetMapping("/getAll")
public List<TOrder0> getAll() {
return tOrder0Service.selectList(null);
}
@GetMapping("/getUser")
public List<TOrder0> getUser(Long userId) {
EntityWrapper<TOrder0> entityWrapper = new EntityWrapper<>();
entityWrapper.eq("user_id", userId);
return tOrder0Service.selectList(entityWrapper);
}
@GetMapping("/getOrder")
public List<TOrder0> getOrder(Long orderId) {
EntityWrapper<TOrder0> entityWrapper = new EntityWrapper<>();
entityWrapper.eq("order_id", orderId);
return tOrder0Service.selectList(entityWrapper);
}
@GetMapping("/addOrder")
public String addOrder(TOrder0 tOrder0) {
tOrder0Service.insert(tOrder0);
System.out.println(tOrder0.getOrderId() % 2);
return "ok";
}
}
这里我说一下,我用的mybatis-plus版本不是很高,如果是高版本的,是没有EntityWrapper这个东西的,它给更新成了QueryWrapper,你别到时候自己去引入自己的maven依赖,然后说我代码不对头。
最后就是最重要的yml配置文件了。
mybatis-plus:
mapper-locations: classpath*:com/zyx/mapper/mapping/*.xml
typeAliasesPackage: com.zyx.entity
sharding:
jdbc:
####ds1
datasource:
names: book
book:
username: root
password: password
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/book
#### 分片配置
config:
sharding:
tables:
####t_order表分片策略
####对应entity里的tableName
t_order:
table-strategy:
inline:
#### 根据userid 进行分片
sharding-column: user_id
algorithm-expression: book.t_order_$->{user_id % 2}
actual-data-nodes: book.t_order_$->{0..1}
props:
sql:
### 开启分片日志
show: true
然后测试即可。。这里我只写了单库的水平分表测试,下面写一个水平分表分库的配置,大家可以去试一试,也可以看看别人的配置多试一下,我觉得这个东西还是动手做才能学到东西,只有动手,才知道错在哪里了。举一反三嘛。
水平分库的配置如下,大致流程是有两个数据库zyx0和zyx1,然后里面有t_order_0和t_order_1两张表,结构一样的,根据user_id来判断到底该去哪个数据库,哪张表:
mybatis-plus:
mapper-locations: classpath*:com/zyx/mapper/mapping/*.xml
typeAliasesPackage: com.zyx.entity
sharding:
jdbc:
####ds1
datasource:
names: zyx0,zyx1
zyx0:
username: root
password: password
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/zyx0
zyx1:
username: root
password: password
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/zyx1
#### 分片配置
config:
sharding:
tables:
####t_order表分片策略
t_order:
####这个是分库的策略
database-strategy:
inline:
sharding-column: user_id
algorithm-expression: zyx$->{user_id % 2}
####这个是分表的策略
table-strategy:
inline:
#### 根据userid 进行分片
sharding-column: user_id
algorithm-expression: t_order_$->{user_id % 2}
###分表分库的总数 0到1
actual-data-nodes: zyx$->{0..1}.t_order_$->{0..1}
props:
sql:
### 开启分片日志
show: true
关于垂直分库和分表这里就不写了,可以多去查查官方资料或者别人的配置看一下,都还挺简单的,如果你能看懂上面的,我相信你已经算是掌握sharding-jdbc了。加油。