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. 运行结果

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

相关推荐
Linux运维老纪9 分钟前
Linux 命令清单(Linux Command List)
linux·运维·服务器·数据库·mysql·云计算·运维开发
骑牛小道士27 分钟前
java基础 迭代Iterable接口以及迭代器Iterator
java
代码吐槽菌1 小时前
基于微信小程序的智慧乡村旅游服务平台【附源码】
java·开发语言·数据库·后端·微信小程序·小程序·毕业设计
界面开发小八哥1 小时前
企业级Java开发工具MyEclipse v2025.1——支持AI编码辅助
java·ide·人工智能·myeclipse
可问 可问春风1 小时前
Java中的ArrayList方法
java
大苏打seven2 小时前
Java学习笔记(多线程):ReentrantLock 源码分析
java·笔记·学习
白舟的博客2 小时前
做好一个测试开发工程师第二阶段:java入门:idea新建一个project后默认生成的.idea/src/out文件文件夹代表什么意思?
java·开发语言·intellij-idea
biubiubiu07062 小时前
Mysql
数据库·mysql
凌辰揽月2 小时前
眨眼睛查看密码工具类
java·开发语言·数据库
张张张3122 小时前
4.8学习总结 贪心算法+Stream流
java·学习