1、准备服务器
比如商城项目中,有用户、订单等系统,数据库在设计时用户信息与订单信息在同一表中。这里创建用户服务、订单服务实现数据库的用户信息和订单信息垂直分片
服务器规划:使用docker
方式创建如下容器
-
服务器:容器名
server-user
,端口3301
-
服务器:容器名
server-order
,端口3302
1.1、创建server-user容器
step1:创建容器:
docker run -d \
-p 3301:3306 \
-v /dongguo/server/user/conf:/etc/mysql/conf.d \
-v /dongguo/server/user/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name server-user \
mysql:8.0.29
step2:登录MySQL服务器
#进入容器:
docker exec -it server-user env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码插件
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
step3:创建数据库:
CREATE DATABASE db_user;
USE db_user;
CREATE TABLE t_user (
id BIGINT AUTO_INCREMENT,
uname VARCHAR(30),
PRIMARY KEY (id)
);
1.2、创建server-order容器
step1:创建容器:
docker run -d \
-p 3302:3306 \
-v /dongguo/server/order/conf:/etc/mysql/conf.d \
-v /dongguo/server/order/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name server-order \
mysql:8.0.29
step2:登录MySQL服务器:
#进入容器:
docker exec -it server-order env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码插件
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
step3:创建数据库:
CREATE DATABASE db_order;
USE db_order;
CREATE TABLE t_order (
id BIGINT AUTO_INCREMENT,
order_no VARCHAR(30),
user_id BIGINT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);
1.3查看:
step1:查看创建的容器
docker ps
step2:navicat连接数据库
server-user :3301
server-order:3302
2、程序实现
2.1、创建实体类
package com.dongguo.shardingjdbc.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
@TableName("t_order")
@Data
public class Order {
@TableId(type = IdType.AUTO)
private Long id;
private String orderNo;
private Long userId;
private BigDecimal amount;
}
2.2、创建Mapper
package com.dongguo.shardingjdbc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dongguo.shardingjdbc.entity.Order;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
2.3、配置垂直分片
application.yml
# 应用名称
spring:
application:
name: sharding-jdbc-demo
profiles:
active: dev
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
# url: jdbc:shardingsphere:classpath:shardingsphere-readwrite.yaml
url: jdbc:shardingsphere:classpath:shardingsphere-sharding.yaml
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
# 请求前缀
pathMapping: /
shardingsphere-sharding.yaml
# 数据源配置
dataSources:
server-user:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://192.168.122.150:3301/db_user
username: root
password: 123456
server-order:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://192.168.122.150:3302/db_order
username: root
password: 123456
#规则配置
rules:
- !SHARDING
tables:
# 逻辑表名
t_user:
# 值由数据源名 + 表名组成,以小数点分隔。
actualDataNodes: server-user.t_user
t_order:
actualDataNodes: server-order.t_order
#属性配置
props:
sql-show: true
3、测试垂直分片
package com.dongguo.shardingjdbc;
import com.dongguo.shardingjdbc.entity.Order;
import com.dongguo.shardingjdbc.entity.User;
import com.dongguo.shardingjdbc.mapper.OrderMapper;
import com.dongguo.shardingjdbc.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.math.BigDecimal;
/**
* @author dongguo
* @date 2023/8/14
* @description:
*/
@SpringBootTest
public class ShardingTest {
@Autowired
private UserMapper userMapper;
@Autowired
private OrderMapper orderMapper;
/**
* 垂直分片:插入数据测试
*/
@Test
public void testInsertOrderAndUser(){
User user = new User();
user.setUname("张三");
userMapper.insert(user);
Order order = new Order();
order.setOrderNo("SP202308140001");
order.setUserId(user.getId());
order.setAmount(new BigDecimal(100));
orderMapper.insert(order);
}
/**
* 垂直分片:查询数据测试
*/
@Test
public void testSelectFromOrderAndUser(){
User user = userMapper.selectById(1L);
Order order = orderMapper.selectById(1L);
System.out.println(user);
System.out.println(order);
}
}
测试插入方法
2023-08-14 20:01:20.447 INFO 22292 --- [ main] ShardingSphere-SQL : Logic SQL: INSERT INTO t_user ( uname ) VALUES ( ? )
2023-08-14 20:01:20.447 INFO 22292 --- [ main] ShardingSphere-SQL : Actual SQL: server-user ::: INSERT INTO t_user ( uname ) VALUES (?) ::: [张三]
2023-08-14 20:01:20.499 INFO 22292 --- [ main] ShardingSphere-SQL : Logic SQL: INSERT INTO t_order ( order_no,
user_id,
amount ) VALUES ( ?,
?,
? )
2023-08-14 20:01:20.499 INFO 22292 --- [ main] ShardingSphere-SQL : Actual SQL: server-order ::: INSERT INTO t_order ( order_no,
user_id,
amount ) VALUES (?, ?, ?) ::: [SP202308140001, 1, 100]
在server-user数据源的t_user表中插入用户信息
在server-order数据源t_order表中插入订单信息
查看数据库
t_user
t_order
测试查询方法
2023-08-14 20:06:40.659 INFO 9948 --- [ main] ShardingSphere-SQL : Logic SQL: SELECT id,uname FROM t_user WHERE id=?
2023-08-14 20:06:40.660 INFO 9948 --- [ main] ShardingSphere-SQL : Actual SQL: server-user ::: SELECT id,uname FROM t_user WHERE id=? ::: [1]
2023-08-14 20:06:40.719 INFO 9948 --- [ main] ShardingSphere-SQL : Logic SQL: SELECT id,order_no,user_id,amount FROM t_order WHERE id=?
2023-08-14 20:06:40.719 INFO 9948 --- [ main] ShardingSphere-SQL : Actual SQL: server-order ::: SELECT id,order_no,user_id,amount FROM t_order WHERE id=? ::: [1]
User(id=1, uname=张三)
Order(id=1, orderNo=SP202308140001, userId=1, amount=100.00)
实现了最基本的标准垂直分片场景