sharding-jdbc结合mybatis实现分库分表功能
最近忙于项目已经好久几天没写博客了,前2篇文章我给大家介绍了搭建基础springMvc+mybatis的maven工程,这个简单框架已经可以对付一般的小型项目。但是我们实际项目中会碰到很多复杂的场景,比如数据量很大的情况下如何保证性能。今天我就给大家介绍数据库分库分表的优化,本文介绍mybatis结合当当网的sharding-jdbc分库分表技术(原理这里不做介绍)
首先在pom文件中引入需要的依赖
- <dependency>
- <groupId>com.dangdang</groupId>
- <artifactId>sharding-jdbc-core</artifactId>
- <version>1.4.2</version>
- </dependency>
- <dependency>
- <groupId>com.dangdang</groupId>
- <artifactId>sharding-jdbc-config-spring</artifactId>
- <version>1.4.0</version>
- </dependency>
二、新建一个sharding-jdbc.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:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.dangdang.com/schema/ddframe/rdb
- http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd">
- <rdb:strategy id="tableShardingStrategy" sharding-columns="user_id" algorithm-class="com.meiren.member.common.sharding.MemberSingleKeyTableShardingAlgorithm"/>
- <rdb:data-source id="shardingDataSource">
- <rdb:sharding-rule data-sources="dataSource">
- <rdb:table-rules>
- <rdb:table-rule logic-table="member_index" actual-tables="member_index_tbl_${[0,1,2,3,4,5,6,7,8,9]}${0..9}" table-strategy="tableShardingStrategy"/>
- <rdb:table-rule logic-table="member_details" actual-tables="member_details_tbl_${[0,1,2,3,4,5,6,7,8,9]}${0..9}" table-strategy="tableShardingStrategy"/>
- </rdb:table-rules>
- </rdb:sharding-rule>
- </rdb:data-source>
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="shardingDataSource" />
- </bean>
- </beans>
这里我简单介绍下一些属性的含义,
<rdb:strategy id="tableShardingStrategy" sharding-columns="user_id" algorithm-class="com.meiren.member.common.sharding.MemberSingleKeyTableShardingAlgorithm"/> 配置分表规则器 sharding-columns:分表规 则
依赖的名(根据user_id取模分表),algorithm-class:分表规则的实现类
<rdb:sharding-rule data-sources="dataSource"> 这里填写关联数据源(多个数据源用逗号隔开),
<rdb:table-rule logic-table="member_index" actual-tables="member_index_tbl_${[0,1,2,3,4,5,6,7,8,9]}${0..9}" table-strategy="tableShardingStrategy"/> logic-table:逻辑表名(mybatis中代替的表名)actual-tables:
数据库实际的表名,这里支持inline表达式,比如:member_index_tbl_${0..2}会解析成member_index_tbl_0,member_index_tbl_1,member_index_tbl_2;member_index_tbl_${[a,b,c]}会被解析成
member_index_tbl_a,member_index_tbl_b和member_index_tbl_c,两种表达式一起使用的时候,会采取笛卡尔积的方式:member_index_tbl_${[a,b]}${0..2}解析为member_index_tbl_a0,member_index_tbl_a1 member_index_tbl_a2,member_index_tbl_b0,member_index_tbl_b1,member_index_tbl_b2;table-strategy:前面定义的分表规则器;
三、配置好改文件后,需要修改之前我们的spring-dataSource的几个地方,把sqlSessionFactory和transactionManager原来关联的dataSource统一修改为shardingDataSource(这一步作用就是把数据源全部托管给sharding去管理)
四、实现分表(分库)逻辑,我们的分表逻辑类需要实现SingleKeyTableShardingAlgorithm接口的三个方法doBetweenSharding、doEqualSharding、doInSharding
- /**
- * 分表逻辑
- * @author zhangwentao
- *
- */
- public class MemberSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long> {
- /**
- * sql between 规则
- */
- public Collection<String> doBetweenSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
- Collection<String> result = new LinkedHashSet<String>(tableNames.size());
- Range<Long> range = (Range<Long>) shardingValue.getValueRange();
- for (long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
- Long modValue = i % 100;
- String modStr = modValue < 10 ? "0" + modValue : modValue.toString();
- for (String each : tableNames) {
- if (each.endsWith(modStr)) {
- result.add(each);
- }
- }
- }
- return result;
- }
- /**
- * sql == 规则
- */
- public String doEqualSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
- Long modValue = shardingValue.getValue() % 100;
- String modStr = modValue < 10 ? "0" + modValue : modValue.toString();
- for (String each : tableNames) {
- if (each.endsWith(modStr)) {
- return each;
- }
- }
- throw new IllegalArgumentException();
- }
- /**
- * sql in 规则
- */
- public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
- Collection<String> result = new LinkedHashSet<String>(tableNames.size());
- for (long value : shardingValue.getValues()) {
- Long modValue = value % 100;
- String modStr = modValue < 10 ? "0" + modValue : modValue.toString();
- for (String tableName : tableNames) {
- if (tableName.endsWith(modStr)) {
- result.add(tableName);
- }
- }
- }
- return result;
- }
- }
五、以上四步,我们就完成了sharding-jdbc的搭建,我们可以写一个测试demo来检查我们的成果
- <select id="getDetailsById" resultType="com.meiren.member.dataobject.MemberDetailsDO"
- parameterType="java.lang.Long">
- select user_id userId ,qq,email from member_details where user_id =#{userId} limit 1
- </select>
- private static final String SERVICE_PROVIDER_XML = "/spring/member-service.xml";
- private static final String BEAN_NAME = "idcacheService";
- private ClassPathXmlApplicationContext context = null;
- IdcacheServiceImpl bean = null;
- IdcacheDao idcacheDao;
- @Before
- public void before() {
- context= new ClassPathXmlApplicationContext(
- new String[] {SERVICE_PROVIDER_XML});
- idcacheDao=context.getBean("IdcacheDao", IdcacheDao.class);
- }
- @Test
- public void getAllCreditActionTest() {
- // int id = bean.insertIdcache();
- Long s=100l;
- MemberDetailsDO memberDetailsDO=idcacheDao.getDetailsById(s);
- System.out.println("QQ---------------------"+memberDetailsDO.getQq());
- }
打印sql语句,输出结果:QQ-------------------------------------100,证明成功!
注意点:这次搭建过程中,我有碰到一个小坑,就是执行的时候会报错:,官方文档是有解决方案:引入 <context:property-placeholder location="classpath:/member_service.properties" ignore-unresolvable="true" /> ,引入这行代码的时候,·必须要要把这边管理配配置文件的bean删除,换句话说,即Spring容器仅允许最多定义一个PropertyPlaceholderConfigurer(或<context:property-placeholder/>),其余的会被Spring忽略掉(当时搞了半天啊)
小结:这次给大家分享了sharding-jdbc的配置是为了解决大数据量进行分库分表的架构,下一张,我将介绍拆分业务所需的duboo+zookeeper的配置(分布式),欢迎关注!
sharding-jdbc结合mybatis实现分库分表功能的更多相关文章
- sharding demo 读写分离 U (分库分表 & 不分库只分表)
application-sharding.yml sharding: jdbc: datasource: names: ds0,ds1,dsx,dsy ds0: type: com.zaxxer.hi ...
- 分库分表(5) ---SpringBoot + ShardingSphere 实现分库分表
分库分表(5)--- ShardingSphere实现分库分表 有关分库分表前面写了四篇博客: 1.分库分表(1) --- 理论 2.分库分表(2) --- ShardingSphere(理论) 3. ...
- Sharding-JDBC分库分表简单示例
1. 简介 Sharding是一个简单的分库分表中间件,它不需要依赖于其他的服务,即可快速应用在实际项目的分库分表策略中. 2. 初始化数据库(db0.db1.db2) 1 #创建数据库db0 2 C ...
- 采用Sharding-JDBC解决分库分表
源码:Sharding-JDBC(分库分表) 一.Sharding-JDBC介绍 1,介绍 Sharding-JDBC是当当网研发的开源分布式数据库中间件,从 3.0 开始Sharding-JDBC被 ...
- Mycat读写分离、主从切换、分库分表的操作记录
系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...
- 海量数据分库分表方案(二)技术选型与sharding-jdbc实现
上一章已经讲述分库分表算法选型,本章主要讲述分库分表技术选型 文中关联上一章,若下文出现提及其时,可以点击 分库分表算法方案与技术选型(一) 主要讲述 框架比较 sharding-jdbc.zdal ...
- 分库分表后跨分片查询与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亿.订单表更夸张, ...
随机推荐
- pycharm git无法使用问题(待解决)
PyCharm 2017.3.1 (Community Edition)Build #PC-173.3942.36, built on December 14, 2017JRE: 1.8.0_152- ...
- H3C配置FTP服务器
H3C配置FTP服务器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.FTP协议简介 1.FTP协议是互联网上广泛使用的文件传输协议 FTP文件传送协议(File Transf ...
- CentOS 6.9/7通过yum安装指定版本的MySQL
一.安装CENTOS 6 # wget http://repo.mysql.com/mysql57-community-release-el6.rpm && rpm -ivh mysq ...
- tomcat配置好后,启动eclipse中的server,不能出现有猫的页面,提示404
原因:tomcat与eclipse中的server未关联起来 解决办法:双击servers中的server,在Server Locations中选中第二项,保存之后再进行刚才的操作就好了.
- Mybatis 学习总结
1 Mybatis入门 1.1 单独使用jdbc编程问题总结 1.1.1 jdbc程序 public static void main(String[] args) { Connection conn ...
- entity framework 时间操作
).FirstOrDefault(); if (useractiveentity == null) { UserActive userActive = new UserActive(); userAc ...
- 图片和流的相互转化 (c/s)
//图片转化为流保存: Stream ms; byte[] picbyte; OpenFileDialog open = new OpenFileDialog(); open.Filter = &qu ...
- luogu P1357 花园
传送门 先考虑朴素dp,设\(f_{i,j}\)表示推了\(i\)次,前\(m\)个点的状态为二进制数\(j\)(这里记放C为1),转移的时候枚举下一位放什么,还要考虑是否满足C的个数\(\leq k ...
- MySql 安装与使用图文教程
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内, ...
- servlet相关
servlet是在服务器端运行的一个小程序.一个servlet就是一个java类,并且可以通过“请求-响应”编程模型来访问的这个驻留在服务器内存里的servlet程序. 1.生命周期 2.内置对象 r ...