您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
ShardingSphere-JDBC——数据分片使用手册
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
ShardingSphere-JDBC——数据分片使用手册
Apache ShardingSphere
2021-01-20
IP归属:未知
27040浏览
# 使用Java API ## 引入 Maven 依赖 ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core</artifactId> <version>${shardingsphere.version}</version> </dependency> ``` ## 规则配置 ShardingSphere-JDBC 的 Java API 通过数据源集合、规则集合以及属性配置组成。 以下示例是根据 `user_id` 取模分库, 且根据 `order_id` 取模分表的 2 库 2 表的配置。 ```java // 配置真实数据源 Map<String, DataSource> dataSourceMap = new HashMap<>(); // 配置第 1 个数据源 BasicDataSource dataSource1 = new BasicDataSource(); dataSource1.setDriverClassName("com.mysql.jdbc.Driver"); dataSource1.setUrl("jdbc:mysql://localhost:3306/ds0"); dataSource1.setUsername("root"); dataSource1.setPassword(""); dataSourceMap.put("ds0", dataSource1); // 配置第 2 个数据源 BasicDataSource dataSource2 = new BasicDataSource(); dataSource2.setDriverClassName("com.mysql.jdbc.Driver"); dataSource2.setUrl("jdbc:mysql://localhost:3306/ds1"); dataSource2.setUsername("root"); dataSource2.setPassword(""); dataSourceMap.put("ds1", dataSource2); // 配置 t_order 表规则 ShardingTableRuleConfiguration orderTableRuleConfig = new ShardingTableRuleConfiguration("t_order", "ds${0..1}.t_order${0..1}"); // 配置分库策略 orderTableRuleConfig.setDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("user_id", "dbShardingAlgorithm")); // 配置分表策略 orderTableRuleConfig.setTableShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "tableShardingAlgorithm")); // 省略配置 t_order_item 表规则... // ... // 配置分片规则 ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); shardingRuleConfig.getTables().add(orderTableRuleConfig); // 配置分库算法 Properties dbShardingAlgorithmrProps = new Properties(); dbShardingAlgorithmrProps.setProperty("algorithm-expression", "ds${user_id % 2}"); shardingRuleConfig.getShardingAlgorithms().put("dbShardingAlgorithm", new ShardingSphereAlgorithmConfiguration("INLINE", dbShardingAlgorithmrProps)); // 配置分表算法 Properties tableShardingAlgorithmrProps = new Properties(); tableShardingAlgorithmrProps.setProperty("algorithm-expression", "t_order${order_id % 2}"); shardingRuleConfig.getShardingAlgorithms().put("tableShardingAlgorithm", new ShardingSphereAlgorithmConfiguration("INLINE", tableShardingAlgorithmrProps)); // 创建 ShardingSphereDataSource DataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(shardingRuleConfig), new Properties()); ``` ## 使用 ShardingSphereDataSource 通过 ShardingSphereDataSourceFactory 工厂创建的 ShardingSphereDataSource 实现自 JDBC 的标准接口 DataSource。 可通过 DataSource 选择使用原生 JDBC,或JPA, MyBatis 等 ORM 框架。 以原生 JDBC 使用方式为例: ```java DataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(shardingRuleConfig), new Properties()); String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.user_id=? AND o.order_id=?"; try ( Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, 10); ps.setInt(2, 1000); try (ResultSet rs = ps.executeQuery()) { while(rs.next()) { // ... } } } ``` # 使用 YAML 配置 ## 引入 Maven 依赖 ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core</artifactId> <version>${shardingsphere.version}</version> </dependency> ``` ## 规则配置 ShardingSphere-JDBC 的 YAML 配置文件 通过数据源集合、规则集合以及属性配置组成。 以下示例是根据 `user_id` 取模分库, 且根据 `order_id` 取模分表的 2 库 2 表的配置。 ```yaml # 配置真实数据源 dataSources: # 配置第 1 个数据源 ds0: !!org.apache.commons.dbcp2.BasicDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/ds0 username: root password: # 配置第 2 个数据源 ds1: !!org.apache.commons.dbcp2.BasicDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/ds1 username: root password: rules: # 配置分片规则 - !SHARDING tables: # 配置 t_order 表规则 t_order: actualDataNodes: ds${0..1}.t_order${0..1} # 配置分库策略 databaseStrategy: standard: shardingColumn: user_id shardingAlgorithmName: database_inline # 配置分表策略 tableStrategy: standard: shardingColumn: order_id shardingAlgorithmName: table_inline t_order_item: # 省略配置 t_order_item 表规则... # ... # 配置分片算法 shardingAlgorithms: database_inline: type: INLINE props: algorithm-expression: ds${user_id % 2} table_inline: type: INLINE props: algorithm-expression: t_order_${order_id % 2} ``` ```java // 创建 ShardingSphereDataSource DataSource dataSource = YamlShardingSphereDataSourceFactory.createDataSource(yamlFile); ``` ## 使用 ShardingSphereDataSource 通过 YamlShardingSphereDataSourceFactory 工厂创建的 ShardingSphereDataSource 实现自 JDBC 的标准接口 DataSource。 可通过 DataSource 选择使用原生 JDBC,或JPA, MyBatis 等 ORM 框架。 ```java DataSource dataSource = YamlShardingSphereDataSourceFactory.createDataSource(yamlFile); String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.user_id=? AND o.order_id=?"; try ( Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, 10); ps.setInt(2, 1000); try (ResultSet rs = preparedStatement.executeQuery()) { while(rs.next()) { // ... } } } ``` # 使用 SPRING BOOT STARTER ## 引入 Maven 依赖 ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>${shardingsphere.version}</version> </dependency> ``` ## 规则配置 ```properties # 配置真实数据源 spring.shardingsphere.datasource.names=ds0,ds1 # 配置第 1 个数据源 spring.shardingsphere.datasource.ds0.type=org.apache.commons.dbcp2.BasicDataSource spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/ds0 spring.shardingsphere.datasource.ds0.username=root spring.shardingsphere.datasource.ds0.password= # 配置第 2 个数据源 spring.shardingsphere.datasource.ds1.type=org.apache.commons.dbcp2.BasicDataSource spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/ds1 spring.shardingsphere.datasource.ds1.username=root spring.shardingsphere.datasource.ds1.password= # 配置 t_order 表规则 spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order$->{0..1} # 配置分库策略 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 # 配置分表策略 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 # 省略配置 t_order_item 表规则... # ... # 配置 分片算法 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} 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} ``` ### 使用 JNDI 数据源 如果计划使用 JNDI 配置数据库,在应用容器(如 Tomcat)中使用 ShardingSphere-JDBC 时, 可使用 `spring.shardingsphere.datasource.${datasourceName}.jndiName` 来代替数据源的一系列配置。如: ```properties # 配置真实数据源 spring.shardingsphere.datasource.names=ds0,ds1 # 配置第 1 个数据源 spring.shardingsphere.datasource.ds0.jndi-name=java:comp/env/jdbc/ds0 # 配置第 2 个数据源 spring.shardingsphere.datasource.ds1.jndi-name=java:comp/env/jdbc/ds1 # 省略规则配置... # ... ``` ## 在 Spring 中使用 ShardingSphereDataSource 直接通过注入的方式即可使用 ShardingSphereDataSource;或者将 ShardingSphereDataSource 配置在JPA, MyBatis 等 ORM 框架中配合使用。 ```java @Resource private DataSource dataSource; ``` # 使用 SPRING 命名空间 ## 引入Maven依赖 ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-namespace</artifactId> <version>${shardingsphere.version}</version> </dependency> ``` ## 规则配置 ```xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sharding="http://shardingsphere.apache.org/schema/shardingsphere/sharding" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://shardingsphere.apache.org/schema/shardingsphere/sharding http://shardingsphere.apache.org/schema/shardingsphere/sharding/sharding.xsd "> <!-- 配置真实数据源 --> <!-- 配置第 1 个数据源 --> <bean id="ds0" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/ds0" /> <property name="username" value="root" /> <property name="password" value="" /> </bean> <!-- 配置第 2 个数据源 --> <bean id="ds1" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/ds1" /> <property name="username" value="root" /> <property name="password" value="" /> </bean> <!-- 配置分库策略 --> <sharding:sharding-algorithm id="dbShardingAlgorithm" type="INLINE"> <props> <prop key="algorithm-expression">ds$->{user_id % 2}</prop> </props> </sharding:sharding-algorithm> <sharding:standard-strategy id="dbStrategy" sharding-column="user_id" algorithm-ref="dbShardingAlgorithm" /> <!-- 配置分表策略 --> <sharding:sharding-algorithm id="tableShardingAlgorithm" type="INLINE"> <props> <prop key="algorithm-expression">t_order$->{order_id % 2}</prop> </props> </sharding:sharding-algorithm> <sharding:standard-strategy id="tableStrategy" sharding-column="user_id" algorithm-ref="tableShardingAlgorithm" /> <!-- 配置分布式id生成策略 --> <sharding:key-generate-algorithm id="snowflakeAlgorithm" type="SNOWFLAKE"> <props> <prop key="worker-id">123</prop> </props> </sharding:key-generate-algorithm> <sharding:key-generate-strategy id="orderKeyGenerator" column="order_id" algorithm-ref="snowflakeAlgorithm" /> <!-- 配置sharding策略 --> <sharding:rule id="shardingRule"> <sharding:table-rules> <sharding:table-rule logic-table="t_order" actual-data-nodes="ds${0..1}.t_order_${0..1}" database-strategy-ref="dbStrategy" table-strategy-ref="tableStrategy" key-generate-strategy-ref="orderKeyGenerator" /> </sharding:table-rules> <sharding:binding-table-rules> <sharding:binding-table-rule logic-tables="t_order,t_order_item"/> </sharding:binding-table-rules> <sharding:broadcast-table-rules> <sharding:broadcast-table-rule table="t_address"/> </sharding:broadcast-table-rules> </sharding:rule> <!-- 配置ShardingSphereDataSource --> <shardingsphere:data-source id="shardingDataSource" data-source-names="ds0, ds1" rule-refs="shardingRule"> <props> <prop key="sql-show">false</prop> </props> </shardingsphere:data-source> </beans> ``` ## 在 Spring 中使用 ShardingSphereDataSource 直接通过注入的方式即可使用 ShardingSphereDataSource;或者将 ShardingSphereDataSource 配置在JPA, MyBatis 等 ORM 框架中配合使用。 ```java @Resource private DataSource dataSource; ``` # 强制路由 ## 简介 Apache ShardingSphere 使用 ThreadLocal 管理分片键值进行强制路由。 可以通过编程的方式向 HintManager 中添加分片值,该分片值仅在当前线程内生效。 Hint 的主要使用场景: * 分片字段不存在 SQL 和数据库表结构中,而存在于外部业务逻辑。 * 强制在主库进行某些数据操作。 ## 使用方法 ### 使用 Hint 分片 #### 规则配置 Hint 分片算法需要用户实现 `org.apache.shardingsphere.sharding.api.sharding.hint.HintShardingAlgorithm` 接口。 Apache ShardingSphere 在进行路由时,将会从 HintManager 中获取分片值进行路由操作。 参考配置如下: ```yaml rules: - !SHARDING tables: t_order: actualDataNodes: demo_ds_${0..1}.t_order_${0..1} databaseStrategy: hint: algorithmClassName: xxx.xxx.xxx.HintXXXAlgorithm tableStrategy: hint: algorithmClassName: xxx.xxx.xxx.HintXXXAlgorithm defaultTableStrategy: none: defaultKeyGenerateStrategy: type: SNOWFLAKE column: order_id props: sql-show: true ``` #### 获取 HintManager ```java HintManager hintManager = HintManager.getInstance(); ``` #### 添加分片键值 - 使用 `hintManager.addDatabaseShardingValue` 来添加数据源分片键值。 - 使用 `hintManager.addTableShardingValue` 来添加表分片键值。 > 分库不分表情况下,强制路由至某一个分库时,可使用 `hintManager.setDatabaseShardingValue` 方式添加分片。 通过此方式添加分片键值后,将跳过 SQL 解析和改写阶段,从而提高整体执行效率。 #### 清除分片键值 分片键值保存在 ThreadLocal 中,所以需要在操作结束时调用 `hintManager.close()` 来清除 ThreadLocal 中的内容。 __hintManager 实现了 AutoCloseable 接口,可推荐使用 try with resource 自动关闭。__ #### 完整代码示例 ```java // Sharding database and table with using HintManager String sql = "SELECT * FROM t_order"; try (HintManager hintManager = HintManager.getInstance(); Connection conn = dataSource.getConnection(); PreparedStatement preparedStatement = conn.prepareStatement(sql)) { hintManager.addDatabaseShardingValue("t_order", 1); hintManager.addTableShardingValue("t_order", 2); try (ResultSet rs = preparedStatement.executeQuery()) { while (rs.next()) { // ... } } } // Sharding database without sharding table and routing to only one database with using HintManager String sql = "SELECT * FROM t_order"; try (HintManager hintManager = HintManager.getInstance(); Connection conn = dataSource.getConnection(); PreparedStatement preparedStatement = conn.prepareStatement(sql)) { hintManager.setDatabaseShardingValue(3); try (ResultSet rs = preparedStatement.executeQuery()) { while (rs.next()) { // ... } } } ``` ### 使用 Hint 强制主库路由 #### 获取 HintManager 与基于 Hint 的数据分片相同。 #### 设置主库路由 - 使用 `hintManager.setPrimaryRouteOnly` 设置主库路由。 #### 清除分片键值 与基于 Hint 的数据分片相同。 #### 完整代码示例 ```java String sql = "SELECT * FROM t_order"; try ( HintManager hintManager = HintManager.getInstance(); Connection conn = dataSource.getConnection(); PreparedStatement preparedStatement = conn.prepareStatement(sql)) { hintManager.setPrimaryRouteOnly(); try (ResultSet rs = preparedStatement.executeQuery()) { while (rs.next()) { // ... } } } ```
原创文章,需联系作者,授权转载
上一篇:ShardingSphere-JDBC——分布式事务使用手册(上)
下一篇:Agile Alliance 七步授权法
Apache ShardingSphere
文章数
96
阅读量
231327
作者其他文章
01
突破关系型数据库桎梏:云原生数据库中间件核心剖析
数据库技术的发展与变革方兴未艾,NewSQL的出现,只是将各种所需技术组合在一起,而这些技术组合在一起所实现的核心功能,推动着云原生数据库的发展。 NewSQL的三种分类中,新架构和云数据库涉及了太多与数据库相关的底层实现,为了保证本文的范围不至太过发散,我们重点介绍透明化分片数据库中间件的核心功能与实现原理,另外两种类型的NewSQL在核心功能上类似,但实现原理会有所差别。
01
Apache ShardingSphere数据脱敏全解决方案详解(上)
Apache ShardingSphere针对新业务上线、旧业务改造分别提供了相应的全套脱敏解决方案。
01
Shardingsphere整合Narayana对XA分布式事务的支持(4)
ShardingSphere对于XA方案,提供了一套SPI解决方案,对Narayana进行了整合,Narayana初始化流程,开始事务流程,获取连接流程,提交事务流程,回滚事务流程。
01
从中间件到分布式数据库生态,ShardingSphere 5.x革新变旧
5.x 是 Apache ShardingSphere从分库分表中间件向分布式数据库生态转化的里程碑,从 4.x 版本后期开始打磨的可插拔架构在 5.x 版本已逐渐成型,项目的设计理念和 API 都进行了大幅提升。欢迎大家测试使用!
最新回复
丨
点赞排行
共0条评论
Apache ShardingSphere
文章数
96
阅读量
231327
作者其他文章
01
突破关系型数据库桎梏:云原生数据库中间件核心剖析
01
Apache ShardingSphere数据脱敏全解决方案详解(上)
01
Shardingsphere整合Narayana对XA分布式事务的支持(4)
01
从中间件到分布式数据库生态,ShardingSphere 5.x革新变旧
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号