ShardingSphere+JPA+Druid实现分表操作

要在SpringBoot项目中实现分表操作,本文使用的是ShardingSphere+JPA+Druid实现。过程中出现问题记录一下。

  1. 准备MySQL数据库表
    这里准备的是一张主表test_cost,两张从表test_cost_0和test_cost_1,结构需要相同,主表只是声明了表结构,供后端框架提供映射关系,不存储数据,从表是真正存储数据的表。
  2. 引入依赖
xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.6.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.6.0</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>
<!-- Spring Boot Starter Test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.6.0</version>
    <scope>test</scope>
</dependency>
<!-- ShardingSphere -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-crypto</artifactId>
    <version>5.7.8</version> 
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.18</version>
</dependency>
<!-- Druid数据源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>
  1. 配置文件
xml 复制代码
server:
  port: 8080

spring:
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5Dialect
        show_sql: true
        ddl-auto: create-drop
  shardingsphere:
    datasource:
      names: books # 数据库名称
      books:
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
        username: root
        password: 980828
    rules:
      sharding:
        sharding-algorithms: #分片算法配置
          table-inline:
            type: INLINE
            props:
              algorithm-expression: test_cost_$->{ id % 2 }
        key-generators: #主键生成策略
          snowflake:
            type: SNOWFLAKE
            props:
              worker-id: 1
        tables: #分表策略
          test_cost: # 主表名称
            actual-data-nodes: books.test_cost_$->{0..1}
            table-strategy:
              standard:
                sharding-column: id
                sharding-algorithm-name: table-inline
    props:
      sql-show: true

这里的分片算法是根据id字段能否被2整除来分,分到两张从表中。

  1. Repository
java 复制代码
@Repository
public interface TestRepository extends JpaRepository<TestEntity, Long> {
}
  1. 实体类
java 复制代码
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name = "test_cost")
public class TestEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private String gender;
    private String country;
    private BigDecimal cost;

}

在配置文件中配置了主键生成策略和分片算法,此处@GeneratedValue不能选IDENTITY,要选AUTO,由jpa自动选择。@Table的值为主表的表名。

  1. 遇见问题
    项目启动失败,出现了下图所示的异常:

    从sharding官网的FAQ中发现如下解释:

解决方案有两个:

  • 去掉druid-spring-boot-starter,直接使用druid-xxx.jar来替代,这就不会出现两个数据源冲突的问题
  • 仍然使用druid-spring-boot-starter,但是在springboot的启动类上exclude掉DruidDataSourceAutoConfigure这个类,忽略druid连接池的默认数据源配置(@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class}))

这里采用的是第二种方式:

java 复制代码
@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class})
public class SpringbootRedisApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootRedisApplication.class, args);
    }

}
  1. 启动项目,报错:java.sql.SQLException: url not set

    原因是配置文件的数据源处的数据库URL的键应为"url"而不是"jdbc-url"!!!(3中提供的是正确的配置)

    改成url后,重新启动,运行正常。

  2. 运行结果

    成功按照分片算法插入到对应的分表中。

相关推荐
掉鱼的猫1 天前
用 ChatModel 构建 LLM 驱动的 Java 应用
java·llm
4154111 天前
JTS 空间运算实战:线 × 线、线 × 面、面 × 面叠加分析
java·jts·叠加分析
Full Stack Developme1 天前
正则表达式设计及工作原理
数据库·mysql·正则表达式
.Hypocritical.1 天前
数据结构笔记——链表成环/反转 + 有序二叉树(BST)构建、遍历、删除
java·数据结构
谢慧琼1 天前
免费版收银系统支持多账号同时登录吗?
mysql
只会写代码1 天前
一套开箱即用实体反射Lambda链式工具,彻底告别原生反射样板代码
java·程序员·源码
AI人工智能+电脑小能手1 天前
【大白话说Java面试题 第151题】【06_Spring篇】第11题:说一下 Spring Bean 的生命周期?
java·开发语言·后端·spring·面试
骑士雄师1 天前
java面试题:jvm ,mybatis
java·jvm·mybatis
rebibabo1 天前
Java基础(24) | MySQL 原理与优化:事务、存储引擎、索引与锁
mysql··存储引擎·explain·视图·最左前缀·事务acid
广州浮点FLOATLIC1 天前
Creo 许可证利用率怎么优化:制造企业该先看共享规则,还是先看模块占用结构
java·开发语言