spring boot+mybatis-plus怎样使用shardingsphere分库分表,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
一.关于
效果预览:
ShardingSphere是一个数据库中间件,可以实现分库分表、读写分离等,详见官网: https://shardingsphere.apache.org/
这里使用spring boot+mybatis-plus的方式来搭建demo。
二.项目搭建
使用vscode(java开发环境可以百度一下)新建一个spring boot项目,引入lombok、mybatis-plus等:
<properties>
<java.version>11</java.version>
<sharding-sphere.version>4.1.1</sharding-sphere.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--Mybatis-Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- for spring boot -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
<!-- for spring namespace -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.7.2</version>
</dependency>
项目结构:
application.yml配置:
spring:
shardingsphere:
datasource:
names: ds0,ds1
ds0:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ds0?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: 123456
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/ds1?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: 123456
sharding:
tables:
t_order:
actualDataNodes: ds${0..1}.t_order_${0..1}
databaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ds${user_id % 2}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_${order_id % 2}
keyGenerator:
type: SNOWFLAKE
column: order_id
t_order_item:
actualDataNodes: ds${0..1}.t_order_item_${0..1}
databaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ds${user_id % 2}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_item_${order_id % 2}
binding-tables: t_order,t_order_item
broadcast-tables: t_config
defaultDataSourceName: ds0
defaultTableStrategy:
none:
defaultKeyGenerator:
type: SNOWFLAKE
column: order_id
props:
sql.shwo: true
db:分别建ds0和ds1库,并分别建t_order_0、t_order_1和t_order_item_0、t_order_item_1
# Host: localhost (Version 5.7.17)
# Date: 2020-08-23 12:31:22
# Generator: MySQL-Front 6.0 (Build 2.29)
#
# Structure for table "t_order_0"
#
CREATE TABLE `t_order_0` (
`order_id` bigint(11) NOT NULL DEFAULT '0',
`user_id` bigint(1) DEFAULT NULL,
`amount` decimal(18,2) DEFAULT NULL,
`discount` decimal(10,2) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#
# Structure for table "t_order_item_0"
#
CREATE TABLE `t_order_item_0` (
`order_id` bigint(11) NOT NULL DEFAULT '0',
`product_id` bigint(11) DEFAULT NULL,
`product_name` varchar(255) DEFAULT NULL,
`price` decimal(10,2) DEFAULT NULL,
`discount` decimal(10,2) DEFAULT NULL,
`count` int(11) DEFAULT NULL,
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
entity:
Order.java
@Data
@TableName("t_order")
public class Order extends Model<Order> {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long orderId;
private Long userId;
private BigDecimal amount;
private BigDecimal discount;
private LocalDateTime createTime;
public Order(){}
public Order(Long orderId,Long userId,BigDecimal amount,BigDecimal discount,LocalDateTime createTime){
this.orderId=orderId;
this.userId=userId;
this.amount=amount;
this.discount=discount;
this.createTime=createTime;
}
}
OrderItem.java
@Data
@TableName("t_order_item")
public class OrderItem extends Model<OrderItem> {
private Long orderId;
private Long productId;
private String productName;
private BigDecimal price;
private BigDecimal discount;
@TableField("`count`")
private int count;
public OrderItem(){}
public OrderItem(Long orderId,Long productId,String productName,BigDecimal price,BigDecimal discount,int count){
this.orderId=orderId;
this.productId=productId;
this.productName=productName;
this.price=price;
this.discount=discount;
this.count=count;
}
}
mapper:
OrderMapper.java
public interface OrderMapper extends BaseMapper<Order> {
}
OrderItemMapper.java
public interface OrderItemMapper extends BaseMapper<OrderItem> {
}
service:
OrderService.java
public interface OrderService extends IService<Order> {
boolean save(Order order,List<OrderItem> items);
}
OrderServiceImpl.java
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
@Autowired
private OrderItemService orderItemService;
@Transactional(rollbackFor = Exception.class)
@Override
public boolean save(Order order, List<OrderItem> items) {
save(order);
orderItemService.saveBatch(items);
return true;
}
}
OrderItemService.java
public interface OrderItemService extends IService<OrderItem> {
}
OrderItemServiceImpl.java
@Service
public class OrderItemServiceimpl extends ServiceImpl<OrderItemMapper,OrderItem> implements OrderItemService {
}
spring boot启动类:
@MapperScan("com.example.sharding.mapper")
@SpringBootApplication
public class ShardingDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ShardingDemoApplication.class, args);
}
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
三.测试效果
建一个测试类:OrderServiceImplTest.java 并编写测试语句
package com.example.sharding.service.impl;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sharding.entity.Order;
import com.example.sharding.entity.OrderItem;
import com.example.sharding.service.OrderItemService;
import com.example.sharding.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class OrderServiceImplTest {
@Autowired
private OrderService orderService;
@Autowired
private OrderItemService orderItemService;
@Test
public void testSave(){
var order1=new Order(1L,1L,new BigDecimal(22.5),new BigDecimal(1),LocalDateTime.now());
var orderItemList1=new ArrayList<OrderItem>();
orderItemList1.add(new OrderItem(1L,1L,"苹果",new BigDecimal(6),new BigDecimal(1),2));
orderItemList1.add(new OrderItem(1L,2L,"香蕉",new BigDecimal(3.5),new BigDecimal(1),3));
var order2=new Order(2L,1L,new BigDecimal(799),new BigDecimal(1),LocalDateTime.now());
var orderItemList2=new ArrayList<OrderItem>();
orderItemList2.add(new OrderItem(2L,3L,"鞋子1",new BigDecimal(600),new BigDecimal(1),1));
orderItemList2.add(new OrderItem(2L,4L,"衬衣1",new BigDecimal(199),new BigDecimal(1),1));
var order3=new Order(3L,1L,new BigDecimal(399),new BigDecimal(1),LocalDateTime.now());
var orderItemList3=new ArrayList<OrderItem>();
orderItemList3.add(new OrderItem(3L,5L,"鞋子2",new BigDecimal(200),new BigDecimal(1),1));
orderItemList3.add(new OrderItem(3L,6L,"衬衣2",new BigDecimal(199),new BigDecimal(1),1));
var order4=new Order(4L,1L,new BigDecimal(499),new BigDecimal(1),LocalDateTime.now());
var orderItemList4=new ArrayList<OrderItem>();
orderItemList4.add(new OrderItem(4L,7L,"鞋子3",new BigDecimal(300),new BigDecimal(1),1));
orderItemList4.add(new OrderItem(4L,8L,"衬衣3",new BigDecimal(199),new BigDecimal(1),1));
var order5=new Order(5L,1L,new BigDecimal(899),new BigDecimal(1),LocalDateTime.now());
var orderItemList5=new ArrayList<OrderItem>();
orderItemList5.add(new OrderItem(5L,9L,"鞋子4",new BigDecimal(600),new BigDecimal(1),1));
orderItemList5.add(new OrderItem(5L,10L,"衬衣4",new BigDecimal(299),new BigDecimal(1),1));
assertTrue(orderService.save(order1,orderItemList1));
assertTrue(orderService.save(order2,orderItemList2));
assertTrue(orderService.save(order3,orderItemList3));
assertTrue(orderService.save(order4,orderItemList4));
assertTrue(orderService.save(order5,orderItemList5));
}
@Test
public void testQuery(){
var page=new Page<OrderItem>(1,4);
var queryWrapper=new QueryWrapper<OrderItem>();
queryWrapper.orderByAsc("order_id");
var itemPage=orderItemService.page(page,queryWrapper);
assertEquals(4, itemPage.getRecords().size());
assertEquals("苹果", itemPage.getRecords().get(0).getProductName());
}
}
测试通过,看一下数据库的数据:
看完上述内容,你们掌握spring boot+mybatis-plus怎样使用shardingsphere分库分表的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/yunduansing/blog/4524532