前一段时间研究阿里的分库框架cobar-client,cobar-client是基于ibatis的SqlMapClientTemplate进行了一层薄薄的封装,分装成CobarSqlMapClientTemplate,在用户在CRUD的时候可以透明的进行操作,算是现在大多公司分库的一个成熟解决方案,不过现在面临的一些问题:
①不支持分表
②基于ibatis而且2013年后基本维护了,没有进行升级,所以大多公司都基于该思想进行了自己的重写
来看下当当开源的sharding-jdbc,官方网址:https://github.com/dangdangdotcom/sharding-jdbc
先允许我盗一波图:
好了,看了这么多的介绍,感觉还是很高大上的,注意点有:
①对JDBC API进行了原生态的分装,这是与cobar-client不一样的地方,这就是他可以支持多个第三方ORM框架的关键
②可支持=
,BETWEEN
,IN
等操作,说明,JDBC返回结果后,sharding进行了合并操作,这里面肯定会有性能损耗
③支持分表,这也是cobar-client不支持的地方
好了,先简单的按照官方网址的demo实践一发:
先在MySQL中建2个库
分别在这2个库中运行:
- CREATE TABLE IF NOT EXISTS `t_order_0` (
- `order_id` INT NOT NULL,
- `user_id` INT NOT NULL,
- PRIMARY KEY (`order_id`)
- );
- CREATE TABLE IF NOT EXISTS `t_order_item_0` (
- `item_id` INT NOT NULL,
- `order_id` INT NOT NULL,
- `user_id` INT NOT NULL,
- PRIMARY KEY (`item_id`)
- );
- CREATE TABLE IF NOT EXISTS `t_order_1` (
- `order_id` INT NOT NULL,
- `user_id` INT NOT NULL,
- PRIMARY KEY (`order_id`)
- );
- CREATE TABLE IF NOT EXISTS `t_order_item_1` (
- `item_id` INT NOT NULL,
- `order_id` INT NOT NULL,
- `user_id` INT NOT NULL,
- PRIMARY KEY (`item_id`)
- );
新建maven项目
Maven依赖的pom.xml
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.study</groupId>
- <artifactId>sharding-jdbc</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>sharding-jdbc</name>
- <url>http://maven.apache.org</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring.version>3.2.5.RELEASE</spring.version>
- <mybatis.version>3.2.4</mybatis.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.10</version>
- </dependency>
- <dependency>
- <groupId>com.dangdang</groupId>
- <artifactId>sharding-jdbc-core</artifactId>
- <version>1.0.0</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-orm</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-dbcp</groupId>
- <artifactId>commons-dbcp</artifactId>
- <version>1.4</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>${mybatis.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-expression</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.28</version>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.16</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.7.5</version>
- </dependency>
- </dependencies>
- </project>
ShardingJdbc
- package com.study.base;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
- import javax.sql.DataSource;
- import org.apache.commons.dbcp.BasicDataSource;
- import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSource;
- import com.dangdang.ddframe.rdb.sharding.api.rule.BindingTableRule;
- import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
- import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
- import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
- import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
- import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
- public class ShardingJdbc {
- public static void main(String[] args) throws SQLException {
- //数据源
- Map<String, DataSource> dataSourceMap = new HashMap<>(2);
- dataSourceMap.put("sharding_0", createDataSource("sharding_0"));
- dataSourceMap.put("sharding_1", createDataSource("sharding_1"));
- DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap);
- //分表分库的表,第一个参数是逻辑表名,第二个是实际表名,第三个是实际库
- TableRule orderTableRule = new TableRule("t_order", Arrays.asList("t_order_0", "t_order_1"), dataSourceRule);
- TableRule orderItemTableRule = new TableRule("t_order_item", Arrays.asList("t_order_item_0", "t_order_item_1"), dataSourceRule);
- /**
- * DatabaseShardingStrategy 分库策略
- * 参数一:根据哪个字段分库
- * 参数二:分库路由函数
- * TableShardingStrategy 分表策略
- * 参数一:根据哪个字段分表
- * 参数二:分表路由函数
- *
- */
- ShardingRule shardingRule = new ShardingRule(dataSourceRule, Arrays.asList(orderTableRule, orderItemTableRule),
- Arrays.asList(new BindingTableRule(Arrays.asList(orderTableRule, orderItemTableRule))),
- new DatabaseShardingStrategy("user_id", new ModuloDatabaseShardingAlgorithm()),
- new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()));
- DataSource dataSource = new ShardingDataSource(shardingRule);
- 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 pstmt = conn.prepareStatement(sql)) {
- pstmt.setInt(1, 10);
- pstmt.setInt(2, 1001);
- try (ResultSet rs = pstmt.executeQuery()) {
- while(rs.next()) {
- System.out.println(rs.getInt(1));
- System.out.println(rs.getInt(2));
- System.out.println(rs.getInt(3));
- }
- }
- }
- }
- /**
- * 创建数据源
- * @param dataSourceName
- * @return
- */
- private static DataSource createDataSource(String dataSourceName) {
- BasicDataSource result = new BasicDataSource();
- result.setDriverClassName(com.mysql.jdbc.Driver.class.getName());
- result.setUrl(String.format("jdbc:mysql://localhost:3306/%s", dataSourceName));
- result.setUsername("root");
- result.setPassword("");
- return result;
- }
- }
ModuloDatabaseShardingAlgorithm
- package com.study.base;
- import java.util.Collection;
- import java.util.LinkedHashSet;
- import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
- import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
- import com.google.common.collect.Range;
- /**
- *
- * @author lyncc
- *
- */
- public class ModuloDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Integer>{
- @Override
- public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
- for (String each : availableTargetNames) {
- if (each.endsWith(shardingValue.getValue() % 2 + "")) {
- return each;
- }
- }
- throw new IllegalArgumentException();
- }
- @Override
- public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
- Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
- for (Integer value : shardingValue.getValues()) {
- for (String tableName : availableTargetNames) {
- if (tableName.endsWith(value % 2 + "")) {
- result.add(tableName);
- }
- }
- }
- return result;
- }
- @Override
- public Collection<String> doBetweenSharding(Collection<String> availableTargetNames,
- ShardingValue<Integer> shardingValue) {
- Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
- Range<Integer> range = (Range<Integer>) shardingValue.getValueRange();
- for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
- for (String each : availableTargetNames) {
- if (each.endsWith(i % 2 + "")) {
- result.add(each);
- }
- }
- }
- return result;
- }
- }
ModuloTableShardingAlgorithm.java
- package com.study.base;
- import java.util.Collection;
- import java.util.LinkedHashSet;
- import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
- import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
- import com.google.common.collect.Range;
- public final class ModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Integer> {
- /**
- * select * from t_order from t_order where order_id = 11
- * └── SELECT * FROM t_order_1 WHERE order_id = 11
- * select * from t_order from t_order where order_id = 44
- * └── SELECT * FROM t_order_0 WHERE order_id = 44
- */
- public String doEqualSharding(final Collection<String> tableNames, final ShardingValue<Integer> shardingValue) {
- for (String each : tableNames) {
- if (each.endsWith(shardingValue.getValue() % 2 + "")) {
- return each;
- }
- }
- throw new IllegalArgumentException();
- }
- /**
- * select * from t_order from t_order where order_id in (11,44)
- * ├── SELECT * FROM t_order_0 WHERE order_id IN (11,44)
- * └── SELECT * FROM t_order_1 WHERE order_id IN (11,44)
- * select * from t_order from t_order where order_id in (11,13,15)
- * └── SELECT * FROM t_order_1 WHERE order_id IN (11,13,15)
- * select * from t_order from t_order where order_id in (22,24,26)
- * └──SELECT * FROM t_order_0 WHERE order_id IN (22,24,26)
- */
- public Collection<String> doInSharding(final Collection<String> tableNames, final ShardingValue<Integer> shardingValue) {
- Collection<String> result = new LinkedHashSet<>(tableNames.size());
- for (Integer value : shardingValue.getValues()) {
- for (String tableName : tableNames) {
- if (tableName.endsWith(value % 2 + "")) {
- result.add(tableName);
- }
- }
- }
- return result;
- }
- /**
- * select * from t_order from t_order where order_id between 10 and 20
- * ├── SELECT * FROM t_order_0 WHERE order_id BETWEEN 10 AND 20
- * └── SELECT * FROM t_order_1 WHERE order_id BETWEEN 10 AND 20
- */
- public Collection<String> doBetweenSharding(final Collection<String> tableNames, final ShardingValue<Integer> shardingValue) {
- Collection<String> result = new LinkedHashSet<>(tableNames.size());
- Range<Integer> range = (Range<Integer>) shardingValue.getValueRange();
- for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
- for (String each : tableNames) {
- if (each.endsWith(i % 2 + "")) {
- result.add(each);
- }
- }
- }
- return result;
- }
- }
log4j.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
- <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
- <!-- [控制台STDOUT] -->
- <appender name="console" class="org.apache.log4j.ConsoleAppender">
- <param name="encoding" value="GBK" />
- <param name="target" value="System.out" />
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%-5p %c{2} - %m%n" />
- </layout>
- </appender>
- <!-- [公共Appender] -->
- <appender name="DEFAULT-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
- <param name="File" value="${webapp.root}/logs/common-default.log" />
- <param name="Append" value="true" />
- <param name="encoding" value="GBK" />
- <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n" />
- </layout>
- </appender>
- <!-- [错误日志APPENDER] -->
- <appender name="ERROR-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
- <param name="File" value="${webapp.root}/logs/common-error.log" />
- <param name="Append" value="true" />
- <param name="encoding" value="GBK" />
- <param name="threshold" value="error" />
- <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n" />
- </layout>
- </appender>
- <!-- [组件日志APPENDER] -->
- <appender name="COMPONENT-APPENDER"
- class="org.apache.log4j.DailyRollingFileAppender">
- <param name="File" value="${webapp.root}/logs/logistics-component.log" />
- <param name="Append" value="true" />
- <param name="encoding" value="GBK" />
- <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n" />
- </layout>
- </appender>
- <!-- [组件日志] -->
- <logger name="LOGISTICS-COMPONENT">
- <level value="${loggingLevel}" />
- <appender-ref ref="COMPONENT-APPENDER" />
- <appender-ref ref="ERROR-APPENDER" />
- </logger>
- <!-- Root Logger -->
- <root>
- <level value="${rootLevel}"></level>
- <appender-ref ref="DEFAULT-APPENDER" />
- <appender-ref ref="ERROR-APPENDER" />
- <appender-ref ref="console" />
- <appender-ref ref="COMPONENT-APPENDER" />
- </root>
- </log4j:configuration>
好了,按照官方教程说明:
我们现在user_id是10,order_id是1001
我们应该在sharding0库中的t_order_1和t_order_item_1中新建数据:
- INSERT INTO `t_order_1` VALUES ('1001', '10');
- INSERT INTO `t_order_item_1` VALUES ('4', '1001', '2');
好了,准备工作做完了,我们运行main函数,运行结果为:
好了,sharding-jdbc正常工作了
相关推荐
在这个"集成sharding-jdbc实现分库分表.zip"的压缩包中,我们可以深入学习如何将Sharding-JDBC应用于实际项目,以提升系统的性能和可扩展性。 1. **Sharding-JDBC简介** Sharding-JDBC是Java语言实现的,它工作在...
Sharding-JDBC作为阿里巴巴开源的轻量级Java框架,是实现分库分表的一种优秀选择。本文将深入探讨基于Sharding-JDBC的按月动态分表策略,并结合提供的“sharding-jdbc-demo”样例进行解析。 首先,了解Sharding-...
作为一款高性能、易用性高的数据库水平分片框架,Sharding-JDBC在设计上力求简单高效,它通过直接封装JDBC协议,实现了对传统数据库操作的高度兼容,使得开发者能够在几乎不改动现有代码的基础上完成数据分库分表的...
**标题与描述解析** ...以上就是围绕Sharding-JDBC分库分表实例的详细知识点,通过这些内容,开发者可以了解到如何在实际项目中利用Sharding-JDBC进行数据库的水平扩展,并掌握其核心功能和使用技巧。
Sharding-JDBC是阿里巴巴开源的轻量级Java框架,它可以在不修改业务代码的情况下,通过配置实现数据库的水平扩展,支持分库分表、读写分离等功能。 接下来,我们详细探讨如何使用Spring、MyBatis和Sharding-JDBC来...
总结,Sharding-JDBC作为一个优秀的数据库中间件,通过分库分表和读写分离技术,为Java开发者提供了强大的数据库扩展能力。通过深入学习和实践"shanjupay"项目,我们可以更好地理解和运用这一技术,以应对日益增长的...
标题"sharding-jdbc开源分表框架整合mybatis-demo"表明这是一个示例项目,展示了如何将`sharding-jdbc`这个开源的分库分表框架与`MyBatis`持久层框架集成在一起。这通常涉及到数据库水平扩展、数据分布以及事务管理...
Spring Boot简化了初始化和配置Spring应用的过程,而Sharding-JDBC则为大型数据库提供了一种分库分表的解决方案,以解决单个数据库性能瓶颈的问题。 【标签】"sharding-jdbc 分库分表" 指出这个项目关注的核心功能...
SpringBoot整合Sharding-JDBC是将Sharding-JDBC这一分布式数据库中间件与SpringBoot框架结合,以实现数据分片、读写分离等高级数据库管理功能。这个完整的代码示例覆盖了Sharding-JDBC的主要技术点,使开发者可以...
Sharding-JDBC是由阿里巴巴开源的轻量级Java框架,它定位为数据库中间件,提供了一种无需修改现有应用代码就能实现数据库分库分表的能力。Sharding-JDBC完全基于JDBC标准,可以理解为一个增强版的数据库驱动,它工作...
标题"sharding-jdbc之——分库分表实例完整源码.zip"提到了"sharding-jdbc",这是一个用于Java的分布式数据库中间件,它提供了分库分表的功能,帮助解决大数据量下的性能瓶颈问题。"分库分表"是将一个大表的数据分散...
标题"sharding-jdbc分表分库接口版、配置版"提到了"sharding-jdbc",这是一个开源的Java框架,用于解决大数据量下的数据库分库分表问题。"接口版"可能指的是通过API来操作数据库,而"配置版"可能指的是通过配置文件...
这个"mysql分库分表sharding-jdbc-sharding-jdbc-demo.zip"压缩包提供的就是一个使用Sharding-JDBC进行数据库分库分表的示例项目。 Sharding-JDBC的工作原理是通过透明化的JDBC层,将数据路由、分片规则、读写分离...
在本教程中,我们将深入探讨如何使用SpringBoot与Sharding-JDBC进行集成,以实现自定义的数据库分库分表策略。Sharding-JDBC是Apache软件基金会下的一个轻量级Java框架,它允许开发者在不改变原有业务代码和数据库...
【标题】"spring+mybatis+sharding-jdbc"是一个基于Spring框架,结合MyBatis持久层框架和Sharding-JDBC分库分表组件的示例项目。该项目旨在展示如何在实际开发中处理大数据量场景下的数据库扩展问题,通过水平扩展...
【标题】"Sharding-JDBC-Master.zip" 提供了一个完整的示例,展示了如何在实际项目中使用Sharding-JDBC实现MyBatis的分库分表功能。这个压缩包包含了Sharding-JDBC的核心代码,方便开发者参考和学习。 【描述】中...
它支持多种数据库,如MySQL、Oracle等,并且提供读写分离、分库分表等多种功能。 1. **配置读写分离**:在Sharding-JDBC中,读写分离的配置主要涉及数据源和规则定义。数据源是指实际的数据库连接,通常我们会配置...
通过Spring Boot集成Sharding-JDBC和Mybatis-Plus,我们可以轻松地实现数据库的分库分表,从而提升系统的数据处理能力和扩展性。同时,Mybatis-Plus提供的便捷操作使得数据库访问更加高效。在实际开发中,还需要注意...
Sharding-JDBC是阿里巴巴开源的一款轻量级的数据库中间件,它允许开发者在不改变任何数据库语句的情况下,实现分库分表的功能,从而提高系统的读写性能。MyBatis作为流行的持久层框架,与Sharding-JDBC的结合可以...
为了解决这个问题,数据库拆分(即分库分表)成为一种常见的解决方案。本文将以"sharding-jdbc-demo.zip"为例,详细介绍如何使用Sharding-JDBC框架实现按月分表,以及其中涉及的关键技术和实践要点。 Sharding-JDBC...