Sharding-JDBC 按日期时间分库分表
简介
Sharding-JDBC
定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。
- 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
- 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
- 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。
集成sharding-jdbc
首先创建创建数据库和表这是sharding-jdbc所要求的。
create database db_201906;
create database db_201907; use db_201906;
create table t_order_20190614(id int not null auto_increment,order_no varchar(16) NOT NULL,sys_time datetime,PRIMARY KEY (id));
create table t_order_20190615(id int not null auto_increment,order_no varchar(16) NOT NULL,sys_time datetime,PRIMARY KEY (id));
insert into t_order_20190614 values(0,'','2019-06-14 0:0:0');
insert into t_order_20190615 values(0,'','2019-06-15 0:0:0'); use db_201907;
create table t_order_20190714(id int not null auto_increment,order_no varchar(16) NOT NULL,sys_time datetime,PRIMARY KEY (id));
create table t_order_20190715(id int not null auto_increment,order_no varchar(16) NOT NULL,sys_time datetime,PRIMARY KEY (id));
insert into t_order_20190714 values(0,'','2019-07-14 0:0:0');
insert into t_order_20190715 values(0,'','2019-07-15 0:0:0');
接着是pom.xml文件,添加sharding-jdbc到工程中,主要是下面两个依赖:
<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.osource.aurora</groupId>
<artifactId>shardingjdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>shardingjdbc</name>
<url>http://maven.apache.org</url> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <!--sharding-jdbc -->
<dependency>
<groupId>io.shardingjdbc</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>2.0.3</version>
</dependency> <dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.3</version>
</dependency> </dependencies>
<build>
<plugins> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.9.4</version>
<configuration>
<connectionType>developerConnection</connectionType>
</configuration>
</plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<releaseProfiles>release</releaseProfiles>
<autoVersionSubmodules>true</autoVersionSubmodules>
<tagBase>https://github.com/sharding/shardingjdbc-framework.git</tagBase>
<tagNameFormat>v@{project.version}</tagNameFormat>
</configuration>
</plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<skip>true</skip>
<aggregate>true</aggregate>
<charset>UTF-8</charset>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
</configuration>
</plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*.xml</exclude>
</excludes>
</configuration>
</plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- 设置成true在使用maven打包发布时不做junit测试 -->
<skip>true</skip>
</configuration>
</plugin> </plugins>
</build> </project>
首先是数据源配置和库策略、表策略:
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.TableRuleConfiguration;
import io.shardingjdbc.core.api.config.strategy.StandardShardingStrategyConfiguration;
import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource; @Configuration
public class ShardingDataSourceConfiguration { @Value("${spring.datasource.username:root}")
private String username; @Value("${spring.datasource.password:123456}")
private String password; @Value("${spring.datasource.url}")
private String jdbcUrl; @Value("${spring.datasource.driver-class-name}")
private String driverClassName; @Value("${shardingjdbc.sql.show:true}")
private String sqlShow; @Value("${mybatis.mapper-locations:mappper/**/*.xml}")
private String mapperLocations; // 配置sharding-jdbc的DataSource,给上层应用使用,这个DataSource包含所有的逻辑库和逻辑表,应用增删改查时,修改对应sql
// 然后选择合适的数据库继续操作。因此这个DataSource创建很重要。
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource shardingDataSource() throws SQLException { ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); // 订单表配置,可以累计添加多个配置
shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());
// shardingRuleConfig.getTableRuleConfigs().add(getUserTableRuleConfiguration()); // 打印SQL
Properties props = new Properties();
props.put("sql.show", sqlShow); return new ShardingDataSource(shardingRuleConfig.build(createDataSourceMap()),
new ConcurrentHashMap<String, Object>(), props); } // 创建用户表规则
@Bean
TableRuleConfiguration getOrderTableRuleConfiguration() {
TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration(); orderTableRuleConfig.setLogicTable("t_order");
orderTableRuleConfig.setLogicIndex("sys_time"); // 设置数据库策略,传入的是sys_time
orderTableRuleConfig.setDatabaseShardingStrategyConfig(
new StandardShardingStrategyConfiguration("sys_time", DatabaseShardingAlgorithm.class.getName()));
// 设置数据表策略,传入的是sys_time
orderTableRuleConfig.setTableShardingStrategyConfig(
new StandardShardingStrategyConfiguration("sys_time", TableShardingAlgorithm.class.getName())); // 设置数据节点,格式为dbxx.tablexx。这里的名称要和map的别名一致。下面两种方式都可以
// orderTableRuleConfig.setActualDataNodes("db_${0..1}.t_order_${0..1}");
orderTableRuleConfig.setActualDataNodes(
"db_201906.t_order_20190614,db_201906.t_order_20190615,db_201907.t_order_20190714,db_201907.t_order_20190715");
// 设置纵列名称
// orderTableRuleConfig.setKeyGeneratorColumnName("ID");
return orderTableRuleConfig;
} // 下面函数是获取数据源,即包含有多少个数据库,读入到系统中存放于map中
private Map<String, DataSource> createDataSourceMap() {
Map<String, DataSource> result = new HashMap<>();
result.put("db_201906",
createDataSource("jdbc:mysql://localhost:3306/db_201906?characterEncoding=utf8&useSSL=false"));
result.put("db_201907",
createDataSource("jdbc:mysql://localhost:3306/db_201907?characterEncoding=utf8&useSSL=false"));
return result;
} private DataSource createDataSource(final String jdbcUrl) {
// 使用默认连接池
BasicDataSource result = new BasicDataSource();
// 指定driver的类名,默认从jdbc url中自动探测
result.setDriverClassName(com.mysql.jdbc.Driver.class.getName());
// 设置数据库路径
result.setUrl(jdbcUrl);
// 设置数据库用户名
result.setUsername(username);
// 设置数据密码
result.setPassword(password);
return result;
} @Bean("sqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(DataSource shardingDataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(shardingDataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactory.setMapperLocations(resolver.getResources(mapperLocations));
return sessionFactory.getObject();
} /**
* - 需要手动配置事务管理器
*/
@Bean
public DataSourceTransactionManager transactitonManager(DataSource shardingDataSource) {
return new DataSourceTransactionManager(shardingDataSource);
} @Bean
public SqlSessionTemplate sqlSessionTmplate(SqlSessionFactory sqlSessionFactory) {
SqlSessionTemplate sqlSessionTmplate = new SqlSessionTemplate(sqlSessionFactory);
return sqlSessionTmplate;
} }
数据库分库策略 DatabaseShardingAlgorithm
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date; import io.shardingjdbc.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.standard.PreciseShardingAlgorithm; public class DatabaseShardingAlgorithm implements PreciseShardingAlgorithm<String> { @Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) { String db_name = "db_";
try {
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(preciseShardingValue.getValue());
String year = String.format("%tY", date);
String mon = String.format("%tm", date);
db_name = db_name + year + mon;
System.out.println("db_name:" + db_name);
} catch (ParseException e) {
e.printStackTrace();
} for (String each : collection) {
System.out.println("db:" + each);
if (each.equals(db_name)) {
return each;
}
} throw new IllegalArgumentException();
} }
数据表分表策略 TableShardingAlgorithm
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date; import io.shardingjdbc.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.standard.PreciseShardingAlgorithm; public class TableShardingAlgorithm implements PreciseShardingAlgorithm<String> { @Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
String tb_name = preciseShardingValue.getLogicTableName() + "_";
try {
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(preciseShardingValue.getValue());
String year = String.format("%tY", date);
String mon = String.format("%tm", date);
String dat = String.format("%td", date);
tb_name = tb_name + year + mon + dat;
System.out.println("tb_name:" + tb_name);
} catch (ParseException e) {
e.printStackTrace();
} for (String each : collection) {
System.out.println("t_order_:" + each);
if (each.equals(tb_name)) {
return each;
}
} throw new IllegalArgumentException(); } }
测试并使用sharding-jdbc
上面基本已经完成了sharding-jdbc的集成,下面将进行测试
创建实体类 Order
import java.io.Serializable;
public class Order implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8759492936340749287L;
private String orderNo;
private String sysTime;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getSysTime() {
return sysTime;
}
public void setSysTime(String sysTime) {
this.sysTime = sysTime;
}
@Override
public String toString() {
return "Order [orderNo=" + orderNo + ", sysTime=" + sysTime + "]";
}
}
创建服务接口类OrderService
import java.util.List;
public interface OrderService {
List<Order> getAll(String sysTime);
}
创建服务接口类实现 OrderServiceImpl
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service("orderService")
public class OrderServiceImpl implements OrderService { @Autowired
private OrderMapper orderMapper; @Override
public List<Order> getAll(String sysTime) {
return orderMapper.findAll(sysTime);
} }
创建 OrderMapper 数据访问层
import java.util.List; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; @Mapper
public interface OrderMapper { @Select("select * from order where sys_time = #{sysTime}")
List<Order> findAll(@Param("sys_time") String sysTime); }
创建 Spring Boot 启动类 SpringBootApplicationTest
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan; @SpringBootApplication
//开启通用注解扫描
@ComponentScan(basePackages = { "org.shardingjdbc" })
@MapperScan(basePackages = { "org.shardingjdbc.mapper.user,org.shardingjdbc.mapper.order" })
@EnableAutoConfiguration
public class SpringBootApplicationTest { public static void main(String[] args) {
SpringApplication.run(SpringBootApplicationTest.class, args);
} }
RestController 测试代码
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class OrderController { @Autowired
@Qualifier("orderService")
private OrderService orderService; @RequestMapping("/get")
public String getOrder() {
List<Order> list = orderService.getAll("2019-06-14 0:0:0");
System.out.println(list);
return "OK";
} }
SpringBootTest 测试方法
import java.util.List; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; /**
* Unit test for simple App.
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootApplicationTest.class)
@EnableAutoConfiguration
public class AppTest { @Autowired
@Qualifier("orderService")
private OrderService orderService; @Test
public void getOrder() {
List<Order> list = orderService.getAll("2019-06-14 0:0:0");
System.out.println(list);
} }
sharding-jdbc 分库分表实现方式到此基本完成
Sharding-JDBC 按日期时间分库分表的更多相关文章
- sharding demo 读写分离 U (分库分表 & 不分库只分表)
application-sharding.yml sharding: jdbc: datasource: names: ds0,ds1,dsx,dsy ds0: type: com.zaxxer.hi ...
- 海量数据分库分表方案(二)技术选型与sharding-jdbc实现
上一章已经讲述分库分表算法选型,本章主要讲述分库分表技术选型 文中关联上一章,若下文出现提及其时,可以点击 分库分表算法方案与技术选型(一) 主要讲述 框架比较 sharding-jdbc.zdal ...
- 采用Sharding-JDBC解决分库分表
源码:Sharding-JDBC(分库分表) 一.Sharding-JDBC介绍 1,介绍 Sharding-JDBC是当当网研发的开源分布式数据库中间件,从 3.0 开始Sharding-JDBC被 ...
- 分库分表后跨分片查询与Elastic Search
携程酒店订单Elastic Search实战:http://www.lvesu.com/blog/main/cms-610.html 为什么分库分表后不建议跨分片查询:https://www.jian ...
- 【大数据和云计算技术社区】分库分表技术演进&最佳实践笔记
1.需求背景 移动互联网时代,海量的用户每天产生海量的数量,这些海量数据远不是一张表能Hold住的.比如 用户表:支付宝8亿,微信10亿.CITIC对公140万,对私8700万. 订单表:美团每天几千 ...
- 分库分表技术演进&最佳实践
每个优秀的程序员和架构师都应该掌握分库分表,这是我的观点. 移动互联网时代,海量的用户每天产生海量的数量,比如: 用户表 订单表 交易流水表 以支付宝用户为例,8亿:微信用户更是10亿.订单表更夸张, ...
- Sharding-JDBC分库分表简单示例
1. 简介 Sharding是一个简单的分库分表中间件,它不需要依赖于其他的服务,即可快速应用在实际项目的分库分表策略中. 2. 初始化数据库(db0.db1.db2) 1 #创建数据库db0 2 C ...
- Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表
Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表 交易所流水表的单表数据量已经过亿,选用Sharding-JDBC进行分库分表.MyBatis-P ...
- 数据库分库分表(sharding)系列【转】
原文地址:http://www.uml.org.cn/sjjm/201211212.asp数据库分库分表(sharding)系列 目录; (一) 拆分实施策略和示例演示 (二) 全局主键生成策略 (三 ...
随机推荐
- js 高阶函数之柯里化
博客地址:https://ainyi.com/74 定义 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且 ...
- 详解Linux系统中10个最危险的命令
概述 大多数的朋友都是主要用的windows系统,基本用鼠标就可以完成所有的操作,但是在Linux系统中很多都是键盘+命令操作电脑的,Linux命令行使用很有趣,但有时候也很危险,尤其是在你不确定你自 ...
- thymeleaf教程-springboot项目中实现thymeleaf自定义标签
转载: http://www.9191boke.com/466119140.html 91博客网 开始: 在使用thymeleaf的过程中有时候需要公共部分渲染页面,这个时候使用自定义标签实现自 ...
- c和c++区别(未整理)
学习完C语言和c++比较一下他们之间的区别: c++是c语言的基础上开发的一种面向对象的编程语言,应用十分广泛,按理说c++可以编译任何c的程序,但是两者还是有细微的差别. c++在c的基础上添加了类 ...
- 《exception》第九次团队作业:Beta冲刺与验收准备(大结局)
一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 1.掌握软件黑盒测试技术:2.学会编制软件项目 ...
- 项目Beta冲刺(团队) --1/7
课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺) 团队名称:葫芦娃队 作业目标:尽力完成 团队博客 队员学号 队员昵称 博客地址 041602421 der himmel ht ...
- everything in javascript can act like an object,
- centos7部署postgresql集群高可用 patroni + etcd 之patroni篇
实验环境:centos7.4纯净版 postgres版本: 9.6.15 etcd版本:3.3.11 patroni版本:1.6.0 patroni介绍可参考:https://github.com/z ...
- SSM框架--Spring+SpringMVC+Mybatis (IDEA)搭建
使用idea创建一个maven项目( 这里演示 的是 web项目) 点击 Finish 然后开始配置 pom.xml文件(添加各种依赖jar包) 先去找 spring 所需的 jar包 jar包中心仓 ...
- 4-html图片与链接
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...