基于Sharding-Jdbc的实战
参考: http://blog.csdn.net/clypm/article/details/54378502
1.创建多个分库
create database sharding_0; create database sharding_1;
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`) );
3.新建maven项目
3.1 名称:sharding-jdbc
目录结构:
com.study.base
com.study.spring
com.study.test
在base下面有3个类
log4j.xml
3.2 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>
3.3 ShardingJdbc.java
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://192.168.1.121:3306/%s", dataSourceName));
result.setUsername("root");
result.setPassword("123456");
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;
}
}
3.4 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>
4.采样的数据分库例子
sharding_0
| t_order_0 | user_id为偶数 order_id为偶数
| t_order_1 | user_id为偶数 order_id为奇数
| t_order_item_0 | user_id为偶数 order_id为偶数
| t_order_item_1 | user_id为偶数 order_id为奇数
sharding_1
| t_order_0 |user_id为奇数 order_id为偶数
| t_order_1 |user_id为奇数 order_id为奇数
| t_order_item_0 |user_id为奇数 order_id为偶数
| t_order_item_1 |user_id为奇数 order_id为奇数
测试案例选用:user_id是10,order_id是1001
我们应该在sharding0库中的t_order_1和t_order_item_1中新建数据:
use sharding_0;
INSERT INTO `t_order_1` VALUES ('1001', '10');
INSERT INTO `t_order_item_1` VALUES ('4', '1001', '2');
好了,准备工作做完了,我们运行main函数,运行结果为:
---------------------------------------------------------------------------------------------
相关推荐
在这个"集成sharding-jdbc实现分库分表.zip"的压缩包中,我们可以深入学习如何将Sharding-JDBC应用于实际项目,以提升系统的性能和可扩展性。 1. **Sharding-JDBC简介** Sharding-JDBC是Java语言实现的,它工作在...
本文将深入探讨基于Sharding-JDBC的按月动态分表策略,并结合提供的“sharding-jdbc-demo”样例进行解析。 首先,了解Sharding-JDBC的核心概念。它主要提供了数据分片、读写分离和分布式事务等功能,无需修改现有...
《基于Sharding-JDBC的SpringBoot+Mybatis整合实践》 在现代的互联网应用中,随着数据量的急剧增长,数据库的水平扩展成为了一个至关重要的问题。Sharding-JDBC作为一个轻量级的Java框架,提供了数据库分片的功能,...
总结来说,“sharding-jdbc-study.zip”是一个全面研究Sharding-JDBC的资源包,包含了从基础概念到实战应用的各个环节。通过深入学习这个项目,开发者不仅能掌握Sharding-JDBC的使用,还能理解分布式数据库的设计...
提供的"shanjupay"可能是一个基于Sharding-JDBC实现的支付系统示例,包含了完整的项目结构、配置文件以及测试用例。通过这个示例,可以学习如何在实际项目中集成Sharding-JDBC,理解其工作原理,并且验证其在处理分...
《基于Sharding-JDBC与MyBatis的分库分表实战》 在现代高并发、大数据量的互联网应用中,数据库的性能优化是至关重要的环节。分库分表是一种常见的解决大数据存储和处理问题的策略,它通过将数据分散到多个数据库或...
基于springboot+springcloud的学习示例,整合springboot admin2.x,sharding-jdbc,分布式session,kafka,rocketmq,websocket,自定义springboot启动器 个人花大量时间整理出的实战资料,内容丰富,文档也很详细。无论做...
【标题】"demo-example-sharding-jdbc-4.1.1.rar" 是一个示例项目,其中包含了使用SpringBoot框架和ShardingJDBC 4.1.1版本进行数据库分表但不分库的实现。这个压缩包旨在展示如何在实际应用中有效地管理和扩展...
**Spring Boot 整合 ShardingSphere (Sharding JDBC) 5.2.0 分库分表实战** 在现代企业级应用开发中,随着业务量的增长,数据库的压力也随之增大,这时就需要进行数据库的分库分表操作来提升系统性能。Spring Boot ...
《SpringBoot+Sharding-JDBC分库分表实战》是一个深度探讨如何在Java环境中利用SpringBoot框架和Sharding-JDBC库实现数据库分库分表的实践教程。本教程旨在帮助开发者掌握在高并发、大数据量场景下,如何有效提升...
《使用ShardingJDBC5.1.1实现按月分库分表、读写分离与自动创表的全面实战》 在现代企业级应用中,数据量的快速增长使得数据库的性能优化成为至关重要的环节。ShardingJDBC作为一款轻量级的Java框架,能够有效地...
【标题】"spring-sharding-mybatis" 涉及到的是Spring Boot集成ShardingSphere(原ShardingJDBC)和MyBatis实现数据库分片的解决方案。这是一个在微服务架构中处理大数据量、高并发场景时,提升系统性能的重要技术。...
作者简介: Adam Lu(刘亚壮),高级软件架构师,Java编程专家,开源分布式消息引擎Mysum发起者、首席架构师及开发者,Android开源消息组件Android-MQ独立...sharding-jdbc的各种实现示例,持续更新中。。。 项目结构简述
《Java分库分表实战:基于Sharding-JDBC与MyBatis》 在现代高并发、大数据量的互联网应用中,数据库性能优化是至关重要的环节。分库分表是一种常见的解决大数据存储和查询效率问题的方法。本文将深入探讨一个基于...
8. **实战演练**:通过“sharding-jdbc-oracle-single”项目,实际操作数据分片过程,从Oracle数据库开始,逐步过渡到DM数据库,加深理论知识与实际操作的结合。 以上就是关于“dm sharejdbc 案例”的核心知识点,...
描述提到"springboot整合ShardingJDBC实战所需资源",这意味着这个压缩包内含了一个使用Spring Boot框架集成ShardingSphere的实战教程或应用实例。ShardingJDBC是ShardingSphere项目的一部分,主要用于数据库分片,...
该项目名为"sharding-jdbc-sample-master",提供了实战演练的示例代码,帮助开发者更好地理解和应用分片技术。 Sharding-JDBC是Apache软件基金会下的开源项目,它的核心思想是在应用程序层面模拟数据库的分片功能,...
在本项目实战中,我们将深入探讨如何在SpringBoot应用中集成ShardingJDBC来实现高效的数据分库分表策略,从而应对亿万级流量的处理挑战。ShardingJDBC是阿里巴巴开源的一款轻量级数据库中间件,它能够在不改变业务...
本项目"分库分表demo.zip"提供了一个基于Spring-Boot和Sharding-JDBC的实战示例,同时结合了MyBatis Generator工具,使得数据库操作更加高效便捷。 首先,让我们详细了解一下分库分表的概念。分库是指将一个大...