最近忙于项目已经好久几天没写博客了,前2篇文章我给大家介绍了搭建基础springMvc+mybatis的maven工程,这个简单框架已经可以对付一般的小型项目。但是我们实际项目中会碰到很多复杂的场景,比如数据量很大的情况下如何保证性能。今天我就给大家介绍数据库分库分表的优化,本文介绍mybatis结合当当网的sharding-jdbc分库分表技术(原理这里不做介绍)

  首先在pom文件中引入需要的依赖

  1. <dependency>
  2. <groupId>com.dangdang</groupId>
  3. <artifactId>sharding-jdbc-core</artifactId>
  4. <version>1.4.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.dangdang</groupId>
  8. <artifactId>sharding-jdbc-config-spring</artifactId>
  9. <version>1.4.0</version>
  10. </dependency>

  二、新建一个sharding-jdbc.xml文件,实现分库分表的配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/tx
  10. http://www.springframework.org/schema/tx/spring-tx.xsd
  11. http://www.springframework.org/schema/context
  12. http://www.springframework.org/schema/context/spring-context.xsd
  13. http://www.dangdang.com/schema/ddframe/rdb
  14. http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd">
  15.  
  16. <rdb:strategy id="tableShardingStrategy" sharding-columns="user_id" algorithm-class="com.meiren.member.common.sharding.MemberSingleKeyTableShardingAlgorithm"/>
  17.  
  18. <rdb:data-source id="shardingDataSource">
  19. <rdb:sharding-rule data-sources="dataSource">
  20. <rdb:table-rules>
  21. <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"/>
  22. <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"/>
  23. </rdb:table-rules>
  24. </rdb:sharding-rule>
  25. </rdb:data-source>
  26.  
  27. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  28. <property name="dataSource" ref="shardingDataSource" />
  29. </bean>
  30. </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

  1. /**
  2. * 分表逻辑
  3. * @author zhangwentao
  4. *
  5. */
  6. public class MemberSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long> {
  7.  
  8. /**
  9. * sql between 规则
  10. */
  11. public Collection<String> doBetweenSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
  12. Collection<String> result = new LinkedHashSet<String>(tableNames.size());
  13. Range<Long> range = (Range<Long>) shardingValue.getValueRange();
  14. for (long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
  15. Long modValue = i % 100;
  16. String modStr = modValue < 10 ? "0" + modValue : modValue.toString();
  17. for (String each : tableNames) {
  18. if (each.endsWith(modStr)) {
  19. result.add(each);
  20. }
  21. }
  22. }
  23. return result;
  24. }
  25.  
  26. /**
  27. * sql == 规则
  28. */
  29. public String doEqualSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
  30. Long modValue = shardingValue.getValue() % 100;
  31. String modStr = modValue < 10 ? "0" + modValue : modValue.toString();
  32. for (String each : tableNames) {
  33. if (each.endsWith(modStr)) {
  34. return each;
  35. }
  36. }
  37. throw new IllegalArgumentException();
  38. }
  39.  
  40. /**
  41. * sql in 规则
  42. */
  43. public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {
  44.  
  45. Collection<String> result = new LinkedHashSet<String>(tableNames.size());
  46. for (long value : shardingValue.getValues()) {
  47. Long modValue = value % 100;
  48. String modStr = modValue < 10 ? "0" + modValue : modValue.toString();
  49. for (String tableName : tableNames) {
  50. if (tableName.endsWith(modStr)) {
  51. result.add(tableName);
  52. }
  53. }
  54. }
  55. return result;
  56. }
  57.  
  58. }

五、以上四步,我们就完成了sharding-jdbc的搭建,我们可以写一个测试demo来检查我们的成果

  1. <select id="getDetailsById" resultType="com.meiren.member.dataobject.MemberDetailsDO"
  2. parameterType="java.lang.Long">
  3. select user_id userId ,qq,email from member_details where user_id =#{userId} limit 1
  4. </select>
  1. private static final String SERVICE_PROVIDER_XML = "/spring/member-service.xml";
  2. private static final String BEAN_NAME = "idcacheService";
  3.  
  4. private ClassPathXmlApplicationContext context = null;
  5. IdcacheServiceImpl bean = null;
  6. IdcacheDao idcacheDao;
  7.  
  8. @Before
  9. public void before() {
  10. context= new ClassPathXmlApplicationContext(
  11. new String[] {SERVICE_PROVIDER_XML});
  12. idcacheDao=context.getBean("IdcacheDao", IdcacheDao.class);
  13. }
  14.  
  15. @Test
  16. public void getAllCreditActionTest() {
  17. // int id = bean.insertIdcache();
  18. Long s=100l;
  19. MemberDetailsDO memberDetailsDO=idcacheDao.getDetailsById(s);
  20. System.out.println("QQ---------------------"+memberDetailsDO.getQq());
  21. }

  打印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实现分库分表功能的更多相关文章

  1. sharding demo 读写分离 U (分库分表 & 不分库只分表)

    application-sharding.yml sharding: jdbc: datasource: names: ds0,ds1,dsx,dsy ds0: type: com.zaxxer.hi ...

  2. 分库分表(5) ---SpringBoot + ShardingSphere 实现分库分表

    分库分表(5)--- ShardingSphere实现分库分表 有关分库分表前面写了四篇博客: 1.分库分表(1) --- 理论 2.分库分表(2) --- ShardingSphere(理论) 3. ...

  3. Sharding-JDBC分库分表简单示例

    1. 简介 Sharding是一个简单的分库分表中间件,它不需要依赖于其他的服务,即可快速应用在实际项目的分库分表策略中. 2. 初始化数据库(db0.db1.db2) 1 #创建数据库db0 2 C ...

  4. 采用Sharding-JDBC解决分库分表

    源码:Sharding-JDBC(分库分表) 一.Sharding-JDBC介绍 1,介绍 Sharding-JDBC是当当网研发的开源分布式数据库中间件,从 3.0 开始Sharding-JDBC被 ...

  5. Mycat读写分离、主从切换、分库分表的操作记录

    系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...

  6. 海量数据分库分表方案(二)技术选型与sharding-jdbc实现

    上一章已经讲述分库分表算法选型,本章主要讲述分库分表技术选型 文中关联上一章,若下文出现提及其时,可以点击 分库分表算法方案与技术选型(一) 主要讲述 框架比较 sharding-jdbc.zdal ...

  7. 分库分表后跨分片查询与Elastic Search

    携程酒店订单Elastic Search实战:http://www.lvesu.com/blog/main/cms-610.html 为什么分库分表后不建议跨分片查询:https://www.jian ...

  8. 【大数据和云计算技术社区】分库分表技术演进&最佳实践笔记

    1.需求背景 移动互联网时代,海量的用户每天产生海量的数量,这些海量数据远不是一张表能Hold住的.比如 用户表:支付宝8亿,微信10亿.CITIC对公140万,对私8700万. 订单表:美团每天几千 ...

  9. 分库分表技术演进&最佳实践

    每个优秀的程序员和架构师都应该掌握分库分表,这是我的观点. 移动互联网时代,海量的用户每天产生海量的数量,比如: 用户表 订单表 交易流水表 以支付宝用户为例,8亿:微信用户更是10亿.订单表更夸张, ...

随机推荐

  1. 搭建Spring4+Spring MVC web工程的最佳实践

    Spring是个非常非常非常优秀的java框架,主要是用它的IOC容器帮我们依赖注入和管理一些程序中的Bean组件,实现低耦合关联,最终提高系统可扩展性和可维护性,用它来辅助我们构建web工程将会感觉 ...

  2. JavaSE学习总结(十八)—— 多线程

    多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能.具有这种能力的系 ...

  3. JAVA记录-@Controller和RequestMapping注解代码介绍

    1.spring-mvc.xml加入配置 <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 --> <context:component ...

  4. CodeChef - AMLEX-Poetic word

    题目链接  Dhinwaji is an acclaimed poet and likes to play with words and letters. He has bought some sti ...

  5. bzoj千题计划297:bzoj3629: [JLOI2014]聪明的燕姿

    http://www.lydsy.com/JudgeOnline/problem.php?id=3629 约数和定理: 若n的标准分解式为 p1^k1 * p2^k2 …… 那么n的约数和= π (Σ ...

  6. 八皇后问题动态演示_Qt5实现

    //核心代码如下 //Queen--放置皇后 #include "queue.h" queue::queue() { *; ; this->board = new bool[ ...

  7. js设定延迟时间的函数

    1.如果想要在执行一个js函数之前延迟一段时间应该怎么做? 答:"setTimeout('update()',1000);" 其中update()函数就是延迟后执行的函数,后面的时 ...

  8. python时间序列画图plot总结

    画图从直觉上来讲就是为了更加清晰的展示时序数据所呈现的规律(包括趋势,随时间变化的规律(一周.一个月.一年等等)和周期性规律),对于进一步选择时序分析模型至关重要.下面主要是基于pandas库总结一下 ...

  9. luogu P1344 [USACO4.4]追查坏牛奶Pollutant Control

    传送门 要求断掉某些边使得两个点不连通,显然是最小割 但是要求选的边数尽量少,,, 可以考虑修改边权(容量),即把边权\(c\)改成\(c*(m+1)+1\) 没了 // luogu-judger-e ...

  10. POJ2421 Constructing Roads【最小生成树】

    题意: 有N个点,有些点已经连接了,然后求出所有点的连接的最短路径是多少. 思路: 最小生成树的变形,有的点已经连接了,就直接把他们的权值赋为0,一样的就做最小生成树. 代码: prime: #inc ...