Springboot2.x +JPA 集成 Apache ShardingSphere 分库分表

分库分表背景:
数据库性能瓶颈:主要分为按照业务来划分或者按照数据量来划分
拆分方式:
水平拆分(每个表的结构都一样):订单表数据量大,我们可以水平拆分 ,分成order表1、order表2、order表3 。。。
垂直拆分:一个多字段的表拆分成多个表
例如:order订单表和oderItem订单详情表
一个订单会购买多件商品,因此,订单order表中会只有一条数据,orderItem订单项表会对应这个订单购买的多件商品

技术选型
组件/框架版本
spring-boot2.4.3
jpa2.4.3
shardingsphere5.0.0-alpha
mysql5.7.3
hikari3.4.5

分库分表

官网文档:
https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/usage/sharding/spring-boot-starter/

1. 引入 Maven 依赖
      <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.0.0-alpha</version>
        </dependency>
2. 规则配置
#分库分表 场景:一个客户多个订单 按照user_id分库 按照order_id 分表

# 配置真实数据源
spring.shardingsphere.datasource.names=ds0,ds1

##############################################################################
# 1.连接池  2.驱动  3.用户名  4.密码  5.连接url  SpringBoot2.x写法
#############################################################################
spring.shardingsphere.datasource.common.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.common.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.common.username=root
spring.shardingsphere.datasource.common.password=root
spring.shardingsphere.datasource.ds_0.jdbc-url=jdbc:mysql://localhost:3306/ds0?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds_1.jdbc-url=jdbc:mysql://localhost:3306/ds1?serverTimezone=UTC&useSSL=false

# 配置 t_order 表规则
#ds$->{0..1} 指的是ds0 ds1 2个数据库
#t_order_$->{0..1} 指的是 t_order_0 t_order_1 2个表
#ds$->{0..1}.t_order_$->{0..1} 指的是ds0 ds1 2个数据库下面的t_order_0和t_order_1 2个表
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order_$->{0..1}

# 配置分库策略
# user_id 指的是按照user_id进行分库
# database-inline 自定义策略名称 下面会用到
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-column=user_id
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-algorithm-name=database-inline

# 配置分表策略
#order_id 指的是按照user_id进行分表
#table-inline 自定义策略名称 下面会用到
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_id
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=table-inline

# 配置 分片算法
#分库分片算法 取模算法
#ds$->{user_id % 2} 指的是user_id与2取模
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds$->{user_id % 2}

#分表分片算法 取模算法
#ds$->{order_id % 2} 指的是order_id与2取模
spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.props.algorithm-expression=t_order_$->{order_id % 2}

# 分片算法配置
#order_id 生成规则
#snowflake 雪花算法
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=order_id
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=snowflake

# 分布式序列算法配置
spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=123

# 具体的属性配置
spring.shardingsphere.props.sql-show=true

3. 实体
package com.gblfy.distributedsharding.entity;

import lombok.Data;

import javax.persistence.*;

@Data
@Entity
@Table(name = "t_order")
public class OrderEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long orderId;

    private Integer userId;
}
4. 接口
package com.gblfy.distributedsharding.mapper;

import com.gblfy.distributedsharding.entity.OrderEntity;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface OrderMapper extends JpaRepository<OrderEntity, Long> {

    OrderEntity findByOrderId(Long orderId);

    List<OrderEntity> findByUserId(Integer userId);
}

5. 表结构
CREATE DATABASE ds0;
use ds0;
CREATE TABLE `t_order_0` (
  `order_id` bigint(20) unsigned NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `t_order_1` (
  `order_id` bigint(20) unsigned NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE DATABASE ds1;
use ds1;
CREATE TABLE `t_order_0` (
  `order_id` bigint(20) unsigned NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `t_order_1` (
  `order_id` bigint(20) unsigned NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
6. 测试类
package com.gblfy.distributedsharding;

import com.gblfy.distributedsharding.entity.OrderEntity;
import com.gblfy.distributedsharding.mapper.OrderMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Random;

@SpringBootTest
class DistributedShardingApplicationTests {

    @Autowired
    private OrderMapper orderMapper;

    @Test
    void insert() {
        OrderEntity entity = new OrderEntity();
        entity.setUserId(new Random().nextInt(999));
        orderMapper.save(entity);
    }

     @Test
    void findByOrderId() {
        //按照order_id分表 ,会查询2次,通过order_id分表,但是不知道哪个库
        orderMapper.findByOrderId(570271967295811584L);
    }

    @Test
    void findByUserId() {
        //按照user_id分库 ,会查询2次,通过user_id分库,但是不知道哪个表
        orderMapper.findByUserId(556);
    }

    @Test
    void updateByOrderId() {
        OrderEntity byOrderId = orderMapper.findByOrderId(570279923689172992L);
        byOrderId.setUserId(1000);
        orderMapper.save(byOrderId);
    }
}
7. 完整pom
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.0.0-alpha</version>
        </dependency>
Spring Boot是一个用于构建独立的、基于生产级别的Spring应用程序的框架。它简化了基于Spring的应用程序的开发过程,并提供了许多开箱即用的功能和特性。 JPA(Java Persistence API)是一套基于对象-关系映射的API规范,它提供了一种方便、统一的方式来访问和管理数据库。通过JPA,我们可以通过编写简单的POJO(Plain Old Java Object)类来表示数据库中的表,并使用JPA提供的注解来进行数据库操作。 ShardingSphere是一个基于Java的开源分布式数据库中间件,它提供了在分片环境下进行数据分片和数据分布式访问的解决方案。ShardingSphere支持多种数据库,如MySQL、Oracle、PostgreSQL等,并且能够提供高性能、高可用性的数据访问服务。 结合Spring Boot和JPA,我们可以很方便地使用JPA来进行数据库操作,并且可以利用Spring Boot的自动配置特性来简化配置。而使用ShardingSphere,我们可以轻松实现数据的分片和分布式访问,从而提高数据库的性能和可扩展性。 在使用Spring Boot集成JPAShardingSphere时,我们可以先配置数据源和JPA的相关属性,然后使用JPA的注解来定义实体类和数据库操作方法。在需要进行分片的情况下,我们可以使用ShardingSphere的配置来定义分片规则,并且在编写DAO层时利用ShardingSphere的API来进行数据访问操作。 综上所述,Spring Boot、JPAShardingSphere是一套完整的技术栈,可以帮助我们快速构建、开发和管理分布式的、高性能的应用程序。这些技术的结合为我们提供了便捷和高效的方式来处理数据库相关的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gblfy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值