cobar client是出自阿里的产品,cobar client只需要引入jar包即可,不需要建立服务。下面的地址是cobar client的帮助文档

http://code.alibabatech.com/docs/cobarclient/zh/

http://www.kuqin.com/system-analysis/20120212/318089.html

分库分表都是在Cobar产品里面的,Cobar分为两类,分别是Cobar Client和Cobar Server,根据业务的需要进行选择,Cobar Server是一组独立的(Stand Alone)的Server集群,Cobar Client就是第三方的Java包,他就直接嵌入到应用上面去。然后他的拆分规则都是直接写到应用的配置文件里面的。这是阿里自主开发的,没有用到外面的一些开源的工具

用到的数据库创建语句:

create database dbtest1;
create database dbtest2;
create database dbtest3;//分别在这三个数据库中创建下面的表:
CREATE TABLE `cont` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`taobaoId` bigint(20) DEFAULT '0',`name` varchar(20) DEFAULT '',`upd_time` datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

cobar是扩展ibatis的 SqlMapClientTemplate的功能,对分布在多个数据库的表进行路由读写的开源软件。但是不支持单库的多表操作。

以下贴出一些关键的代码,详细的可以下载功能进行运行查看:

工程截图:

下面列举一个简单的功能,就spring与ibatis进行整合,在mysql数据库上面进行操作,对cont表进行添加和查询的功能操作:

简单看下service,dao的文件代码

Service:

public interface ContService {/*** 基本插入* * @return*/public Long addCont(Cont cont);/*** 根据主键查询*/public Cont getContByKey(Long id);/*** 根据条件查询* * @param contQuery*            查询条件* @return*/public List<Cont> getContList(ContQuery contQuery);
}

ServiceImpl:

@Service("contService")
public class ContServiceImpl implements ContService {private static final Log log = LogFactory.getLog(ContServiceImpl.class);@ResourceContDAO contDAO;/*** 插入数据库* * @return*/public Long addCont(Cont cont) {try {return contDAO.addCont(cont);} catch (SQLException e) {log.error("dao addCont error.:" + e.getMessage(), e);}return 0L;}/*** 根据主键查找*/public Cont getContByKey(Long id) {try {return contDAO.getContByKey(id);} catch (SQLException e) {log.error("dao getContbyKey error.:" + e.getMessage(), e);}return null;}public List<Cont> getContList(ContQuery contQuery) {try {return contDAO.getContList(contQuery);} catch (SQLException e) {log.error("get Cont list error." + e.getMessage(), e);}return Collections.emptyList();}}

Dao:

@Repository
public class ContDAO {@ResourceSqlMapClientTemplate sqlMapClientTemplate;public Long addCont(Cont cont) throws SQLException {return (Long) this.sqlMapClientTemplate.insert("Cont.insertCont", cont);}/*** 根据主键查找* * @throws SQLException*/public Cont getContByKey(Long id) throws SQLException {Map<String, Object> params = new HashMap<String, Object>();params.put("id", id);Cont result = (Cont) this.sqlMapClientTemplate.queryForObject("Cont.getContByKey", params);return result;}@SuppressWarnings("unchecked")public List<Cont> getContList(ContQuery contQuery) throws SQLException {if (contQuery.getFields() != null && contQuery.getFields() != "") {return (List<Cont>) this.sqlMapClientTemplate.queryForList("Cont.getContListFields", contQuery);}return (List<Cont>) this.sqlMapClientTemplate.queryForList("Cont.getContList", contQuery);}}

1、下面applicationContext.xmlspring配置文件是针对没有在cobar的情况下进行的常规配置:

<?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd"default-lazy-init="false"><description>Spring公共配置</description><context:component-scan base-package="com.hj.cobar"></context:component-scan><bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location"><value>application.development.properties</value></property></bean><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><!-- 基本属性 url、user、password --><property name="url" value="${jdbc_url}"/><property name="username" value="${jdbc_user}"/><property name="password" value="${jdbc_password}"/><!-- 配置初始化大小、最小、最大 --><property name="initialSize" value="1"/><property name="minIdle" value="1"/><property name="maxActive" value="20"/><!-- 配置获取连接等待超时的时间 --><property name="maxWait" value="60000"/><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="60000"/><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="300000"/><property name="validationQuery" value="SELECT 'x'"/><property name="testWhileIdle" value="true"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><property name="poolPreparedStatements" value="false"/><property name="maxPoolPreparedStatementPerConnectionSize" value="20"/><!-- 配置监控统计拦截的filters --><property name="filters" value="stat"/></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 使用annotation定义事务 --><tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/><!-- 配置ibatis的SqlMapClient --><bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"><property name="dataSource" ref="dataSource" />  <property name="configLocation"><value>classpath:/sqlmap-config.xml</value></property></bean><bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"><property name="sqlMapClient" ref="sqlMapClient" />  </bean></beans>

2、下面是在applicationContext.xml使用cobar的配置,一些细节可参考阿里的cobar的帮助文档:

<?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd"default-lazy-init="false"><description>Spring公共配置</description><context:component-scan base-package="com.hj.cobar"></context:component-scan><bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location"><value>application.development.properties</value></property></bean><!-- 配置数据源开始 --><bean id="dataSources" class="com.alibaba.cobar.client.datasources.DefaultCobarDataSourceService"><property name="dataSourceDescriptors"><set><bean class="com.alibaba.cobar.client.datasources.CobarDataSourceDescriptor"><property name="identity" value="partition0"/><property name="targetDataSource" ref="dataSource0"/><property name="targetDetectorDataSource" ref="dataSource0"/></bean><bean class="com.alibaba.cobar.client.datasources.CobarDataSourceDescriptor"><property name="identity" value="partition1"/><property name="targetDataSource" ref="dataSource1"/><property name="targetDetectorDataSource" ref="dataSource1"/></bean><bean class="com.alibaba.cobar.client.datasources.CobarDataSourceDescriptor"><property name="identity" value="partition2"/><property name="targetDataSource" ref="dataSource2"/><property name="targetDetectorDataSource" ref="dataSource2"/></bean></set></property><property name="haDataSourceCreator"><bean class="com.alibaba.cobar.client.datasources.ha.FailoverHotSwapDataSourceCreator"><property name="detectingSql" value="update cobarha set timeflag=CURRENT_TIMESTAMP()"/></bean></property></bean><!-- 数据源0 --><bean id="dataSource0" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${jdbc0.url}" /><property name="username" value="${jdbc0.username}" /><property name="password" value="${jdbc0.password}" /><property name="filters" value="config" /><property name="maxActive" value="5" /><property name="initialSize" value="5" /><property name="maxWait" value="1" /><property name="minIdle" value="5" /><property name="timeBetweenEvictionRunsMillis" value="3000" /><property name="minEvictableIdleTimeMillis" value="300000" /><property name="validationQuery" value="SELECT 'x'" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" /><property name="poolPreparedStatements" value="true" /><property name="maxPoolPreparedStatementPerConnectionSize" value="20" /><!-- <property name="connectionProperties" value="config.decrypt=true" /> --></bean><!-- 数据源1 --><bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${jdbc1.url}" /><property name="username" value="${jdbc1.username}" /><property name="password" value="${jdbc1.password}" /><property name="filters" value="config" /><property name="maxActive" value="5" /><property name="initialSize" value="5" /><property name="maxWait" value="1" /><property name="minIdle" value="5" /><property name="timeBetweenEvictionRunsMillis" value="3000" /><property name="minEvictableIdleTimeMillis" value="300000" /><property name="validationQuery" value="SELECT 'x'" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" /><property name="poolPreparedStatements" value="true" /><property name="maxPoolPreparedStatementPerConnectionSize" value="20" /></bean><!-- 数据源2 --><bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${jdbc2.url}" /><property name="username" value="${jdbc2.username}" /><property name="password" value="${jdbc2.password}" /><property name="filters" value="config" /><property name="maxActive" value="5" /><property name="initialSize" value="5" /><property name="maxWait" value="1" /><property name="minIdle" value="5" /><property name="timeBetweenEvictionRunsMillis" value="3000" /><property name="minEvictableIdleTimeMillis" value="300000" /><property name="validationQuery" value="SELECT 'x'" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" /><property name="poolPreparedStatements" value="true" /><property name="maxPoolPreparedStatementPerConnectionSize" value="20" /></bean>
<!-- 配置数据源结束 -->  <!-- 配置路由规则开始 --><bean id="hashFunction" class="com.hj.cobar.dao.router.HashFunction"></bean><bean id="internalRouter"class="com.alibaba.cobar.client.router.config.CobarInteralRouterXmlFactoryBean"><!-- functionsMap是在使用自定义路由规则函数的时候使用 --><property name="functionsMap"><map><entry key="hash" value-ref="hashFunction"></entry></map></property><property name="configLocations"><list><value>classpath:/dbRule/sharding-rules-on-namespace.xml</value></list></property></bean>
<!-- 配置路由规则结束 -->  <!-- 事务配置 --><bean id="transactionManager" class="com.alibaba.cobar.client.transaction.MultipleDataSourcesTransactionManager"><property name="cobarDataSourceService" ref="dataSources"/></bean><!-- 使用annotation定义事务 --><tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/><!--  iBatis SQL map定义。                                                    --><bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"><!-- 这里配置的dataSource0为默认的数据源,如果找不到数据库的话则到该数据源中查找 --><property name="dataSource" ref="dataSource0" />  <property name="configLocation"><value>classpath:/sqlmap-config.xml</value></property></bean><!-- 工程里一定要使用此工程模板,不能再使用ibatis原生的api,不然有的情况会不经过cobar的过滤 --><bean id="sqlMapClientTemplate" class="com.alibaba.cobar.client.CobarSqlMapClientTemplate"><property name="sqlMapClient" ref="sqlMapClient" /><property name="cobarDataSourceService" ref="dataSources" /><property name="router" ref="internalRouter" /><property name="sqlAuditor"><bean class="com.alibaba.cobar.client.audit.SimpleSqlAuditor" /></property><property name="profileLongTimeRunningSql" value="true" /><property name="longTimeRunningSqlIntervalThreshold" value="3600000" /></bean></beans>

3、在sharding-rules-on-namespace.xml配置cobar的路由规则,因为此路由规则是使用自定义的路由规则,所以还要写一个自定义的规则函数类

<rules><rule><namespace>Cont</namespace><!-- 表达式如果不使用自定义路由规则函数,而是直接使用   taobaoId%2==0这种的话就不用在文件中配置<property name="functionsMap">中了--><shardingExpression>hash.apply(taobaoId) == 0</shardingExpression><shards>partition0</shards></rule><rule><namespace>Cont</namespace><shardingExpression>hash.apply(taobaoId) == 1</shardingExpression><shards>partition1</shards></rule><rule><namespace>Cont</namespace><shardingExpression>hash.apply(taobaoId) == 2</shardingExpression><shards>partition2</shards></rule></rules>

4、自定义的路由规则函数类

hash的一种做法是对taobaoId进行md5加密,然后取前几位(我们这里取前两位),然后就可以将不同的taobaoId哈希到不同的用户表(cont_xx)中了。

通过这个技巧,我们可以将不同的taobaoId分散到256中用户表中,分别是cont_00,user_01 ...... cont_ff。因为taobaoId是数字且递增,根据md5的算法,可以将用户数据几乎很均匀的分别到不同的cont表中。

但是这里有个问题是,如果我们的系统的数据越来越多,势必单张表的数据量越来越大,而且根据这种算法无法扩展表,这又会回到单表量大的问题。

下面只是简单的用求余的方法来返回值

/*** 根据某种自定义的hash算法来进行散列,并根据散列的值进行路由*  常见的水平切分规则有:基于范围的切分, 比如 memberId > 10000 and memberId < 20000基于模数的切分, 比如 memberId%128==1 或者 memberId%128==2 或者...基于哈希(hashing)的切分, 比如hashing(memberId)==someValue等* @author hj**/
public class HashFunction{/*** 对三个数据库进行散列分布* 1、返回其他值,没有在配置文件中配置的,如负数等,在默认数据库中查找* 2、比如现在配置文件中配置有三个结果进行散列,如果返回为0,那么apply方法只调用一次,如果返回为2,*   那么apply方法就会被调用三次,也就是每次是按照配置文件的顺序依次的调用方法进行判断结果,而不会缓存方法返回值进行判断* @param taobaoId* @return*/public int apply(Long taobaoId) {//先从缓存获取 没有则查询数据库//input 可能是taobaoId,拿taobaoId到缓存里去查用户的DB坐标信息。然后把库的编号输出System.out.println("taobaoId:"+taobaoId);int result = (int)(taobaoId % 3);System.out.println("在第"+(result + 1)+"个数据库中");return result;}/**注:只调用一次taobaoId:3354在第1个数据库中注:调用了三次taobaoId:7043在第3个数据库中taobaoId:7043在第3个数据库中taobaoId:7043在第3个数据库中*/}

5、下面是对service的单元测试

/*** cobar的单元测试*/
public class AppTest extends TestCase{ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");ContService contService = (ContService) context.getBean("contService");/*** 没有使用对象查询直接使用基本类型则到默认的数据源中去查找数据*/public void test1(){Cont cont = contService.getContByKey(2L);System.out.println(cont);}/*** 测试添加*/public void test2(){Cont cont = new Cont();cont.setName("gd");Long taobaoId = new Long(new Random().nextInt(10000));System.out.println("#"+taobaoId);cont.setTaobaoId(taobaoId);contService.addCont(cont);}/*** 测试使用对象包含taobaoId属性的进行查找* 使用这种方式可以根据taobaoId分库查找*/public void test3(){ContQuery contQuery = new ContQuery();contQuery.setTaobaoId(2809L);List<Cont> list = contService.getContList(contQuery);if(list != null){System.out.println(list.get(0));}}
}

工程下载地址: http://download.csdn.net/detail/wxwzy738/6698067

Cobar Client的使用相关推荐

  1. 开源的分布式数据库中间件系统Mycat和阿里巴巴Cobar的对比

    mycat 不得不说的缘分 原创 2016年04月15日 15:48:17 27834 1,愕然回首,它在灯火阑珊处 关于mysql集群中间件,以前写在应用程序里面,由开发人员实现,在配置文件里面写多 ...

  2. 阿里巴巴关于Java重要开源项目汇总

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来源:segmentfault.com/a/1190000017346799 1.分布式应用服 ...

  3. 飒!阿里巴巴 29 个吊炸天的开源项目!

    来源:segmentfault.com/a/1190000017346799 1. 分布式应用服务开发的一站式解决方案 Spring Cloud Alibaba Spring Cloud Alibab ...

  4. 这26个阿里 Java 开源项目,你用过几个?

    阅读本文需要5分钟 来源:http://t.cn/E6hvQw5 1.分布式应用服务开发的一站式解决方案 Spring Cloud Alibaba 2. JDBC 连接池.监控组件 Druid 3. ...

  5. 信不信这29 个阿里开源项目里肯定有你用过的?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | sf.gg/a/119000001734679 ...

  6. 阿里开源项目汇总(二十)

    1.分布式应用服务开发的一站式解决方案 Spring Cloud Alibaba 2. JDBC 连接池.监控组件 Druid 3. Java 的 JSON 处理器 fastjson 4. 服务框架 ...

  7. 数据库分库分表(sharding)系列(三) 关于使用框架还是自主开发以及sharding实现层面的考量...

    当团队对系统业务和数据库进行了细致的梳理,确定了切分方案后,接下来的问题就是如何去实现切分方案了,目前在sharding方面有不少的开源框架和产 品可供参考,同时很多团队也会选择自主开发实现,而不管是 ...

  8. 分库分表需要考虑的问题及方案

    https://www.jianshu.com/p/32b3e91aa22c 分库分表的基本思想 Sharding的基本思想就要把一个数据库切分成多个部分放到不同的数据库(server)上,从而缓解单 ...

  9. 【1024】阿里开源项目汇总

    程序员的语言是代码,程序员的交流工具就是开源软件. 通过开源软件,程序员不仅贡献了改变世界的工具,还向同行展示了自己的作品,期望得到交流和反馈, 进一步提高软件的功能和质量.开源已经成为程序员文化的一 ...

最新文章

  1. Spring Boot JPA中使用@Entity和@Table
  2. Java文件I / O基础
  3. mysql 分类汇总_sql多级分类汇总实现介绍
  4. Git:小乌龟报错no supported authentication methods avaiable
  5. 笔记本html连接电视机黑屏是怎么回事,电脑连接电视黑屏是怎么回事
  6. php server host,PHP $ _SERVER ['HTTP_HOST']与$ _SERVER
  7. 【Vue2.0】—Vue脚手架配置代理(二十二)
  8. C++ 檔案、資料夾、路徑處理函式庫:boost::filesystem
  9. Android布局--AbsoluteLayout
  10. 关于 IMPP/XMPP/SIMPLE 这几种即时通讯协议和NAT traversal
  11. scala 函数中嵌套函数_Scala函数–声明,定义,调用和嵌套函数
  12. sap固定资产号码范围_SAP--FI详细解---固定资产
  13. HTML5期末大作业 漫画网站设计——动漫海贼王(10页) 动漫网页设计制作 简单静态HTML网页作品 动漫网页作业成品 学生动漫网站模板
  14. JS报错解决:SyntaxError: Unexpected token 《 in JSON at position 0
  15. 使用C#编写一个读取和判断股票实时成交数据的小工具
  16. 创客学院9天C语言六
  17. Celery源码阅读 result
  18. [小狼毫]安装,现成的拼音配置方案
  19. Java教程:Jasper-pdf打印类
  20. 电脑键盘失灵怎么办?

热门文章

  1. 数据集COCO在目标检测的介绍与使用
  2. 【洛谷题解】P2356 弹珠游戏
  3. 佳能eosr控制环能否计算机控制,关于全画幅微单相机 你可能不知道的十件事
  4. 华南农业大学课设——数据结构课设、Java课设、操作系统课设
  5. 01背包问题【回溯法求解】通俗易懂,适合小白
  6. 【小白爬POJ2431】3.6 探险车加油问 Expedition
  7. 手撕boost/buck
  8. SEO新人如何做网站诊断和策划
  9. 最新科大讯飞麦克风阵列板替代产品来了,附远场录音效果图
  10. 石墨烯优异的光学和电学性能使之成为制造光电探测器的理想材料-供应黑磷烯石墨烯复合材料空心微球 石墨烯/电磁功能化有机微球 石墨烯/阴离子多聚糖复合微球载体 石墨烯/Ag炭微球气凝胶