当前位置: 首页 > news >正文

Sharding-JDBC 使用方法

Sharding-JDBC 使用方法

以下是Sharding-JDBC在Spring Boot项目中的完整使用示例,包含详细的配置和代码实现。

1. Maven依赖配置 (pom.xml)

<dependencies><!-- Spring Boot 核心依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Spring Boot Data JPA --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- Sharding-JDBC --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.3.2</version> <!-- 使用最新稳定版本 --></dependency><!-- MySQL 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
</dependencies>

2. 分片规则配置 (application.yml)

spring:application:name: sharding-jdbc-demo# Sharding-JDBC 配置shardingsphere:datasource:# 数据源名称集合,多数据源以逗号分隔names: ds0,ds1# 第一个数据源配置ds0:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/big_market_0?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=falseusername: rootpassword: roothikari:minimum-idle: 5maximum-pool-size: 20idle-timeout: 30000connection-timeout: 30000pool-name: ds0-pool# 第二个数据源配置ds1:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/big_market_1?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=falseusername: rootpassword: roothikari:minimum-idle: 5maximum-pool-size: 20idle-timeout: 30000connection-timeout: 30000pool-name: ds1-pool# 分片规则配置rules:sharding:# 表规则配置tables:# 订单表分片配置t_order:# 数据节点配置,格式为:数据源名称.表名actual-data-nodes: ds$->{0..1}.t_order$->{0..3}# 数据库分片策略database-strategy:standard:# 分片键sharding-column: user_id# 分片算法名称sharding-algorithm-name: database_inline# 表分片策略table-strategy:standard:# 分片键sharding-column: order_id# 分片算法名称sharding-algorithm-name: table_inline# 主键生成策略key-generate-strategy:column: order_idkey-generator-name: snowflake# 订单项表分片配置t_order_item:actual-data-nodes: ds$->{0..1}.t_order_item$->{0..3}database-strategy:standard:sharding-column: user_idsharding-algorithm-name: database_inlinetable-strategy:standard:sharding-column: order_idsharding-algorithm-name: table_inlinekey-generate-strategy:column: order_item_idkey-generator-name: snowflake# 分片算法配置sharding-algorithms:# 数据库分片算法database_inline:type: INLINEprops:algorithm-expression: ds$->{user_id % 2}# 表分片算法table_inline:type: INLINEprops:algorithm-expression: t_order$->{order_id % 4}# 主键生成器配置key-generators:snowflake:type: SNOWFLAKEprops:worker-id: 123# 绑定表配置,用于优化多表关联查询binding-tables:- t_order,t_order_item# 广播表配置,在所有分片库中都存在的表broadcast-tables:- t_config# 模式配置mode:type: Memory# 属性配置props:sql-show: true

3. 自定义分片算法实现

3.1 数据库分片算法

import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;/*** 自定义复杂分片算法实现* 支持多个分片键的分片策略*/
public class CustomComplexDatabaseShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {/*** 数据库分片算法实现* * @param availableTargetNames 可用的数据源名称集合* @param shardingValue 分片键值对象* @return 分片后的数据源名称集合*/@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<Long> shardingValue) {// 定义返回的数据源集合Set<String> result = new LinkedHashSet<>();// 获取分片键及其对应的值Map<String, Collection<Long>> columnNameAndShardingValuesMap = shardingValue.getShardingValuesMap();// 假设我们使用user_id作为分片键if (columnNameAndShardingValuesMap.containsKey("user_id")) {Collection<Long> userIds = columnNameAndShardingValuesMap.get("user_id");// 对每个user_id值进行分片计算for (Long userId : userIds) {// 使用简单的取模算法String targetDataSource = "ds" + (userId % availableTargetNames.size());if (availableTargetNames.contains(targetDataSource)) {result.add(targetDataSource);}}}return result;}
}

3.2 表分片算法

import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;import java.util.Collection;/*** 精确分片算法实现* 用于处理 = 和 IN 条件的分片*/
public class CustomPreciseTableShardingAlgorithm implements PreciseShardingAlgorithm<Long> {/*** 表分片算法实现* * @param availableTargetNames 可用的表名称集合* @param shardingValue 分片键值对象* @return 分片后的表名称*/@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {// 获取分片键名称String columnName = shardingValue.getColumnName();// 获取分片键值Long value = shardingValue.getValue();// 遍历所有可用表名,找到匹配的表for (String tableName : availableTargetNames) {// 例如:根据订单ID取模选择表if (tableName.endsWith(String.valueOf(value % 4))) {return tableName;}}// 如果没有找到匹配的表,抛出异常throw new UnsupportedOperationException("无法找到匹配的表: " + availableTargetNames + " for value: " + value);}
}

4. 实体类定义

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;/*** 订单实体类*/
@Entity
@Table(name = "t_order")
public class Order {@Id@Column(name = "order_id")private Long orderId;@Column(name = "user_id")private Long userId;@Column(name = "total_amount")private BigDecimal totalAmount;@Column(name = "status")private String status;@Column(name = "create_time")private Date createTime;// getter和setter方法省略// ...
}

5. Repository接口

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;import java.util.List;/*** 订单数据访问层*/
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {/*** 根据用户ID查询订单* Sharding-JDBC会自动路由到对应的分片*/List<Order> findByUserId(Long userId);/*** 自定义查询* Sharding-JDBC会自动解析SQL并路由到对应的分片*/@Query("SELECT o FROM Order o WHERE o.userId = ?1 AND o.status = ?2")List<Order> findByUserIdAndStatus(Long userId, String status);
}

6. 服务层实现

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;/*** 订单服务实现*/
@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;/*** 创建订单* 使用事务确保数据一致性*/@Transactionalpublic Order createOrder(Order order) {// Sharding-JDBC会根据分片规则自动将订单保存到对应的数据库和表return orderRepository.save(order);}/*** 根据用户ID查询订单* Sharding-JDBC会根据user_id路由到对应的数据库分片*/public List<Order> getOrdersByUserId(Long userId) {return orderRepository.findByUserId(userId);}/*** 根据用户ID和状态查询订单*/public List<Order> getOrdersByUserIdAndStatus(Long userId, String status) {return orderRepository.findByUserIdAndStatus(userId, status);}
}

7. 控制器示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** 订单控制器*/
@RestController
@RequestMapping("/api/orders")
public class OrderController {@Autowiredprivate OrderService orderService;/*** 创建订单*/@PostMappingpublic Order createOrder(@RequestBody Order order) {return orderService.createOrder(order);}/*** 根据用户ID查询订单*/@GetMapping("/user/{userId}")public List<Order> getOrdersByUserId(@PathVariable Long userId) {return orderService.getOrdersByUserId(userId);}/*** 根据用户ID和状态查询订单*/@GetMapping("/user/{userId}/status/{status}")public List<Order> getOrdersByUserIdAndStatus(@PathVariable Long userId, @PathVariable String status) {return orderService.getOrdersByUserIdAndStatus(userId, status);}
}

8. 自定义Sharding-JDBC配置类 (可选)

如果需要通过Java代码配置Sharding-JDBC,可以使用以下配置类:

import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;/*** Sharding-JDBC 配置类*/
@Configuration
public class ShardingJdbcConfig {/*** 创建ShardingDataSource*/@Beanpublic DataSource dataSource() throws SQLException {// 配置真实数据源Map<String, DataSource> dataSourceMap = new HashMap<>();dataSourceMap.put("ds0", createDataSource("ds0"));dataSourceMap.put("ds1", createDataSource("ds1"));// 配置分片规则ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();// 添加表规则配置shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfiguration());shardingRuleConfig.getTableRuleConfigs().add(orderItemTableRuleConfiguration());// 配置默认数据库分片策略shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new CustomPreciseDatabaseShardingAlgorithm()));// 配置默认表分片策略shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new CustomPreciseTableShardingAlgorithm()));// 创建ShardingDataSourcereturn ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());}/*** 创建数据源*/private DataSource createDataSource(String dataSourceName) {// 这里实现数据源创建逻辑// ...return null; // 实际使用时返回真实的数据源}/*** 订单表规则配置*/private TableRuleConfiguration orderTableRuleConfiguration() {TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration("t_order", "ds${0..1}.t_order${0..3}");// 设置主键生成策略// tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "order_id"));return tableRuleConfig;}/*** 订单项表规则配置*/private TableRuleConfiguration orderItemTableRuleConfiguration() {TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration("t_order_item", "ds${0..1}.t_order_item${0..3}");// 设置主键生成策略// tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "order_item_id"));return tableRuleConfig;}
}

9. 注意事项

  1. 数据库初始化:在使用Sharding-JDBC之前,需要手动创建好所有分片数据库和表。

  2. SQL兼容性:部分复杂SQL可能不被Sharding-JDBC支持,需要参考官方文档进行SQL优化。

  3. 事务支持:Sharding-JDBC支持本地事务,但对于分布式事务,需要使用Seata等额外组件。

  4. 监控与运维:建议配置sql-show: true来查看实际执行的SQL,方便调试和优化。

  5. 性能优化

    • 使用绑定表减少笛卡尔积查询
    • 合理设计分片键,避免热点数据
    • 对分片表进行合理的索引设计

这个示例涵盖了Sharding-JDBC的核心使用方法,包括数据源配置、分片规则定义、分片算法实现以及在Spring Boot项目中的集成使用。根据实际业务需求,可以调整分片策略和算法实现。

http://www.dtcms.com/a/357090.html

相关文章:

  • 为什么不能创建泛型数组?
  • C++并发编程-17. 线程安全的链表
  • Unity EventTrigger 动态添加事件
  • flume事务机制详解:保障数据可靠性的核心逻辑
  • 项目中为什么使用SpringBoot?
  • 晨控CK-FR102ANS与欧姆龙NX系列PLC配置EtherNet/IP通讯连接手册
  • 如何规划一年、三年、五年的IP发展路线图?
  • Android 端 QGroundControl 控制 PC 端Gazebo Sim 仿真无人机
  • 龙迅#LT7642GX适用于4路HDMI2.1/DP/TPYE-C转HDMI+LVDS/MIPI混合开关应用,分辨率高达8K30HZ !
  • ADFS 和 OAuth 的区别
  • 第三届机械工程与先进制造智能化技术研讨会(MEAMIT2025)
  • 打造企业内部的“技术桥梁”:超级用户机制如何助力制造企业高效运维
  • “聚势同行・创赢未来”淮南高新区科技型企业沙龙——2025大数据企业专场成功举办
  • 解决RTX3070魔改16G在UBUNTU中黑屏问题
  • AI模型库哪个好?2025年主流AI模型选型指南与API成本对比推荐
  • 在现场把“数据”变成可用的力量 —— 谈EG8200Lite的实战价值
  • 七牛云灵矽AI实践:构建可扩展智能体的开放协议与架构
  • C++实现快速反转一个数的算法
  • “上门做饭”平台的核心技术栈与运营壁垒是什么?
  • linux系统学习(13.系统管理)
  • 【混合开发】Android+webview模拟crash崩溃补充说明
  • Electron 项目来实现文件下载和上传功能(AI)
  • Martin Fowler分享了他对大语言模型(LLM)与软件开发现状的一些思考
  • 【机器学习深度学习】Embedding 与 RAG:让 AI 更“聪明”的秘密
  • AC上网行为安全管理
  • 【完整源码+数据集+部署教程】停车位状态检测系统源码和数据集:改进yolo11-DCNV2-Dynamic
  • 深入理解会话状态管理:多轮对话与API最佳实践
  • 【AI】常见8大LLM大语言模型地址
  • 什么是策略模式?策略模式能带来什么?——策略模式深度解析:从概念本质到Java实战的全维度指南
  • VisualStudio 将xlsx文件嵌入到资源中访问时变String?