`
dragonsoar
  • 浏览: 206712 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

summercool-ddl框架简介 (二)

 
阅读更多

简介:轻量封装Ibatis3

         因为本人在国内最大的电子商务公司工作期间,深感一个好的分表分库框架可以大大提高系统的承载能力及系统的灵活性,而一个不好的分表分库方案,则让系统在大数据量处理的时候非常郁闷。所以, 在根据笔者在从事电子商务开发的这几年中,对各个应用场景而开发的一个轻量封装Ibatis3的一个分表分库框架。

         笔者工作的这几年之中,总结并开发了如下几个框架: summercool(Web 框架,已经应用于某国内大型网络公司的等重要应用)、summercool-hsf(基于Netty实现的RPC框架,已经应用国内某移动互联网公司)、 summercool-ddl(基于Mybaits的分表分库框架,已经应用国内某移动互联网公司);相继缓存方案、和消息系统解决方案也会慢慢开源。 Summercool框架做为笔者的第一个开源框架

 

1.依赖

<dependency>
    <groupId>org.summercool</groupId>
    <artifactId>summercool-ddl</artifactId>
    <version>1.0</version>
</dependency>

 源码svn地址:http://summercool-ddl.googlecode.com/svn/trunk

2.准备Sql映射文件

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ">
<mapper namespace="NS-User">
    <insert id="insertUser" parameterType="org.summercool.mybatis.demo.dao.entity.UserEntity">
        insert into $[user]$(
            id,
            name
        ) values (
            #{id},
            #{name}
        )
    </insert>
</mapper>

 注意此处,对于需要分表或分库的表,使用“$[table name]$”这种方式表示。

3.Spring配置

<?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:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"
    default-autowire="byName">
    <bean id="dataSourceMaster" class="com.jolbox.bonecp.BoneCPDataSource"
        destroy-method="close">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl">
            <value>${demo.datasource.master.jdbcUrl}</value>
        </property>
        <property name="username" value="${demo.datasource.master.username}" />
        <property name="password" value="${demo.datasource.master.password}" />
        <property name="idleConnectionTestPeriodInMinutes" value="5" />
        <property name="idleMaxAgeInMinutes" value="30" />
        <property name="maxConnectionsPerPartition" value="30" />
        <property name="minConnectionsPerPartition" value="5" />
        <property name="partitionCount" value="2" />
        <property name="acquireIncrement" value="5" />
        <property name="statementsCacheSize" value="150" />
        <property name="releaseHelperThreads" value="8" />
        <property name="connectionTestStatement" value="select 1 from dual" />
    </bean>
     
    <bean id="dataSourceSlave" class="com.jolbox.bonecp.BoneCPDataSource"
        destroy-method="close">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl">
            <value>${demo.datasource.slave.jdbcUrl}</value>
        </property>
        <property name="username" value="${demo.datasource.slave.username}" />
        <property name="password" value="${demo.datasource.slave.password}" />
        <property name="idleConnectionTestPeriodInMinutes" value="5" />
        <property name="idleMaxAgeInMinutes" value="30" />
        <property name="maxConnectionsPerPartition" value="30" />
        <property name="minConnectionsPerPartition" value="5" />
        <property name="partitionCount" value="2" />
        <property name="acquireIncrement" value="5" />
        <property name="statementsCacheSize" value="150" />
        <property name="releaseHelperThreads" value="8" />
        <property name="connectionTestStatement" value="select 1 from dual" />
    </bean>
    <bean id="demoSqlSessionFactory"
        class="org.summercool.mybatis.spring.support.SqlSessionFactoryBean">
        <property name="mainDataSource" ref="dataSourceMaster" />
        <property name="shardDataSourceList">
            <util:list>
                <ref bean="dataSourceSlave" />
            </util:list>
        </property>
        <property name="mapperLocations">
            <array>
                <value>classpath:mybatis/user-mapper.xml</value>
            </array>
        </property>
        <property name="shardStrategy">
            <map>
                <entry key="Shard-User">
                    <value>org.summercool.mybatis.demo.shard.UserShardStrategy</value>
                </entry>
            </map>
        </property>
    </bean>
    <bean id="userDao" class="org.summercool.mybatis.demo.dao.impl.UserDaoImpl">
        <property name="sqlSessionFactory" ref="demoSqlSessionFactory"/>
    </bean>
</beans>
从上面的配置文件中,可以看到,注入了两个DataSource,分别代表两个物理库。

然后再添加类型为org.summercool.mybatis.spring.support.SqlSessionFactoryBean的bean描述,并将两个DataSource关联到该bean的主库和备库(备库可以有多个)字段。

同时,需要设置分表策略字段shardStrategy,该字段的类型是Map,添加分表策略时,Key即为分表策略的名称,Value则为具体的分表策略实现。如上,注册了一个名称为"fr"的分表策略实现类com.gexin.contact.utils.shard.ContactShardStrategy。

4.分表策略的实现

package org.summercool.mybatis.demo.shard;
import java.util.Map;
import javax.sql.DataSource;
import org.summercool.mybatis.ShardParam;
import org.summercool.mybatis.strategy.ShardStrategy;
/**
 * 
 * @author Kolor
 */
public class UserShardStrategy extends ShardStrategy {
    @Override
    public DataSource getTargetDataSource() {
        ShardParam shardParam = getShardParam();
        //
        Long param = (Long) shardParam.getShardValue();
        Map<String, DataSource> map = this.getShardDataSources();
        if (param > 100) {
            return map.get("dataSourceSlave");
        }
        return getMainDataSource();
    }
    @Override
    public String getTargetSql() {
        String targetSql = getSql();
        ShardParam shardParam = getShardParam();
        //
        Long param = (Long) shardParam.getShardValue();
        String tableName = "user_" + (param % 2);
        targetSql = targetSql.replaceAll("\\$\\[user\\]\\$", tableName);
        return targetSql;
    }
}
可以看到这个分表策略继承自org.summercool.mybatis.strategy.ShardStrategy,并实现其两个抽象方法getTargetDataSource和getTargetSql,分别代表获取目标DataSource和获取目标Sql。

目标DataSource通过解析分表参数,按设计好的策略获取。

目标Sql同样通过解析分表参数,生成真正的表名,然后用字符串替换的方式获取真正的Sql。

5.Dao层实现

package org.summercool.mybatis.demo.dao.impl;
import org.summercool.mybatis.ShardParam;
import org.summercool.mybatis.demo.dao.UserDao;
import org.summercool.mybatis.demo.dao.entity.UserEntity;
import org.summercool.mybatis.spring.support.SqlSessionDaoSupport;
/**
 *  
 * @author
 */
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
    public boolean insertUser(UserEntity user) {
        ShardParam shardParam = new ShardParam("Shard-User", user.getId(), user);
         
        return getSqlSession().insert("NS-User.insertUser", shardParam) > 0;
    }
}

Dao层实现没有特别的地方,仅有的一点就是,对于需要分表分库的操作,需要传入分表参数(ShardParam)

ShardParam shardParam = new ShardParam("Shard-User", user.getId(), user);

我们来看看ShardParam的定义:

package org.summercool.mybatis;
public class ShardParam {
    public static final ShardParam NO_SHARD = new ShardParam();
    private String name;
    private Object shardValue;
    private Object params;
    public ShardParam() {
    }
    public ShardParam(String name, Object shardValue, Object params) {
        super();
        this.name = name;
        this.shardValue = shardValue;
        this.params = params;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Object getShardValue() {
        return shardValue;
    }
    public void setShardValue(Object shardValue) {
        this.shardValue = shardValue;
    }
    public Object getParams() {
        return params;
    }
    public void setParams(Object params) {
        this.params = params;
    }
}

 构造函数,第一个参数是分表分库策略的名字(即在第二小节中提到的"fr"),第二个参数是分表参数,第三个参数是真正提交到数据库的参数。

6. Spring事务配置

<?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:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util-3.0.xsd"
    default-autowire="byName">
     
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:config/config.properties</value>
            </list>
        </property>
        <property name="fileEncoding" value="UTF-8" />
    </bean>
     
    <bean id="userService" class="org.summercool.mybatis.demo.service.impl.UserServiceImpl"/>
     
    <!-- 事务配置 -->
    <bean name="userTransactionManager"
        class="org.summercool.mybatis.spring.support.MultiDataSourceTransactionManager">
    </bean>
    <tx:advice id="userTxAdvice" transaction-manager="userTransactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="NOT_SUPPORTED" />
        </tx:attributes>
    </tx:advice>
     
    <aop:config>
        <!-- UserService事务管理 -->
        <aop:pointcut id="userServiceOperation"
            expression="execution(* org.summercool.mybatis.demo.service..*Service.*(..))" />
        <aop:advisor advice-ref="userTxAdvice" pointcut-ref="userServiceOperation" />
    </aop:config>
</beans>
 目前只支持XA分布式事务。
分享到:
评论
3 楼 khlee 2014-09-03  
博主你好,你的svn上的代码看不了,能否发一份给我呢? khlee@126.com
2 楼 dragonsoar 2013-05-23  
lovit 写道
你好,MultiDataSourceTransactionManager实现多数据源的原理是什么?

你看一下代码,基于树状的一个管理~
1 楼 lovit 2013-05-21  
你好,MultiDataSourceTransactionManager实现多数据源的原理是什么?

相关推荐

    summercool-ddl:从 code.google.compsummercool-ddl 自动导出

    《Summercool-DDL:基于MyBatis的分库分表框架详解》 在现代的互联网应用中,随着数据量的快速增长,单表存储的数据量往往容易达到瓶颈,从而影响系统的性能和稳定性。为了解决这一问题,分布式数据库和分库分表...

    summercool-hsf:自动从code.google.compsummercool-hsf导出

    summercool(Web 框架,已经应用于某国内大型网络公司的等重要应用)、summercool-hsf(基于Netty实现的RPC框架,已经应用国内某移动互联网公司)、 summercool-ddl(基于Mybaits的分表分库框架,已经应用国内某...

    summercool:从 code.google.compsummercool 自动导出

    summercool( Web框架,已经应用于某国内大型网络公司的等重要应用)、summercool-hsf(基于Netty实现的RPC框架,已经应用国内某移动互联网公司)、summercool-ddl(基于Mybaits的分表分库框架,已经应用国内某移动...

    Ibatis之分表分库解决方案

    在实际项目中,`summercool-ddl`可能是一个包含数据库创建脚本的文件,用于在实施分库分表前准备数据库结构。这些脚本可能包含了创建分片表的DDL语句,以及可能的视图和索引,以优化查询性能。 总之,Ibatis的分库...

    SSO单点登录概要设计说明书.doc

    SSO单点登录概要设计说明书.doc

    奥塔北煤矿6.0 Mta新井设计说明书.docx

    奥塔北煤矿6.0 Mta新井设计说明书.docx

    基于S7-200 PLC和组态王的喷泉控制系统设计与实现

    内容概要:本文详细介绍了基于S7-200 PLC和组态王软件构建喷泉控制系统的全过程。首先明确了系统的IO分配,包括启动按钮、停止按钮以及喷泉水泵的连接方式。接着展示了梯形图程序的设计,涵盖了基本的启停控制逻辑、定时循环和模式切换机制。随后提供了详细的接线图原理图,解释了输入输出部分的具体接线方法。最后讲述了组态王的画面设计,包括创建工程、定义变量和绘制监控界面等步骤。此外还分享了一些调试过程中遇到的问题及解决方案。 适合人群:对自动化控制感兴趣的初学者和技术人员,尤其是那些希望深入了解PLC编程和人机界面设计的人群。 使用场景及目标:适用于小型喷泉项目的实际控制系统开发,旨在帮助读者掌握PLC编程技巧、熟悉组态软件的应用,并能够独立完成类似的自动化控制系统设计。 其他说明:文中不仅包含了理论知识讲解,还附带了许多实践经验分享,如硬件配置建议、常见错误规避措施等,有助于提高实际操作能力。

    计算机二级PPT精选二十套(标红).jpg

    计算机二级PPT精选二十套(标红)

    保险公司IT变更管理流程设计说明书.doc.doc

    保险公司IT变更管理流程设计说明书.doc.doc

    毕业设计说明书A江坝后式厂房双曲拱坝设计.pdf

    毕业设计说明书A江坝后式厂房双曲拱坝设计.pdf

    《计算机二级MS精选300道选择题.docx》

    内容概要:文档《计算机二级MS精选300道选择题.docx》涵盖了计算机二级考试中Microsoft Office软件(Word、Excel、PowerPoint)及计算机基础知识的选择题。题目涉及软件操作技巧、功能应用、常见问题解决等方面,旨在帮助考生熟悉并掌握相关知识点,提高应试能力。文档内容详尽,涵盖面广,从基础操作到高级应用均有涉及,适合考生全面复习备考。 适用人群:准备参加计算机二级考试的学生及相关从业人员,特别是需要强化Office软件操作技能和计算机基础知识的人员。 使用场景及目标:①考生可以在复习过程中使用这些选择题进行自我检测,巩固所学知识;②教师可以将其作为教学辅助材料,帮助学生更好地理解和掌握课程内容;③培训机构可以用这些题目作为测试题库,评估学员的学习效果。 其他说明:文档不仅提供了大量的选择题,还详细解析了每道题目的答案,有助于考生深入理解知识点。此外,题目内容紧跟最新考试大纲,确保考生能够获得最有效的备考资料。

    基于多目标黏菌优化算法(MOSMA)的SVM参数优化及其在回归预测中的应用

    内容概要:本文介绍了一种创新的方法,利用多目标黏菌优化算法(MOSMA)来优化支持向量机(SVM)的参数C和gamma,从而提高回归预测的效果。首先详细解释了MOSMA的工作原理,包括黏菌权重更新、快速非支配排序以及自适应参数调整等关键技术点。接着展示了具体的Python代码实现,涵盖数据预处理、适应度函数定义、参数更新规则等方面。实验结果显示,在风电功率预测等多个应用场景中,相较于传统的网格搜索方法,MOSMA能够更快更有效地找到最优参数组合,显著提升了预测性能。 适合人群:从事机器学习研究或应用开发的技术人员,尤其是关注SVM参数优化及回归预测领域的从业者。 使用场景及目标:适用于需要进行高效参数寻优的回归预测任务,如风电功率预测、设备负载预测等。主要目标是通过改进SVM参数配置,获得更高的预测精度和更好的泛化能力。 其他说明:文中提供了完整的代码示例和详细的实施步骤指导,帮助读者快速理解和应用这一先进的优化技术。此外,还讨论了一些常见的注意事项和技术细节,如数据标准化、参数范围设定、并行化改造等。

    毕业设计 某油库设计说明书.pdf

    毕业设计 某油库设计说明书.pdf

    Q235钢板焊接工艺设计说明书.docx

    Q235钢板焊接工艺设计说明书.docx

    75t循环流化床锅炉设计说明书.doc

    75t循环流化床锅炉设计说明书.doc

    (最新修订版)直列四缸柴油机配气机构设计毕业论文设计说明书.doc

    (最新修订版)直列四缸柴油机配气机构设计毕业论文设计说明书.doc

    DeepSeek大模型生态报告:中国AI技术突破及其全球影响分析

    内容概要:《deepseek大模型生态报告 2025年2月》详细介绍了DeepSeek大模型的背景、应用现状、技术特点及其产业生态。DeepSeek由杭州深度求索公司创立,通过一系列技术创新,如多层注意力架构(MLA)、FP8混合精度训练框架、DualPipe跨节点通信等,显著降低了训练成本和提高了模型性能。DeepSeek在国内和国际市场迅速崛起,登顶苹果应用商店免费APP下载排行榜,并被多家企业和机构接入,包括华为、三大运营商、微软、英伟达等。其开源策略和低成本优势对全球科技供应链和资本市场产生了深远影响,尤其是在AI领域。 适合人群:对人工智能、大模型技术感兴趣的科技爱好者、研究人员、企业家及政策制定者。 使用场景及目标:①了解DeepSeek大模型的技术创新和应用现状;②探讨DeepSeek对全球AI产业生态的影响;③分析DeepSeek在不同行业(如金融、医疗、教育、制造等)的具体应用案例。 其他说明:报告还涵盖了各国政府及相关机构对DeepSeek的态度和政策回应,以及DeepSeek对未来AI技术发展和国际竞争格局的启示。此外,报告深入剖析了DeepSeek在技术架构、数据策略和工程实践方面的突破,揭示了其成功背后的组织文化和创新机制。

    基于粒子群算法的电动汽车区域综合能源系统三方定价优化研究

    内容概要:本文详细介绍了利用粒子群算法解决电动汽车区域综合能源系统中光伏电站、充电桩运营商和电网公司在定价上的三方博弈问题。通过MATLAB代码实现了粒子群算法的具体应用,包括参数设置、适应度函数设计、粒子更新策略以及结果可视化。文中展示了如何将三方定价变量编码成多维粒子,并通过目标函数计算和约束处理确保粒子在合理的解空间内搜索最优解。最终得到的电价曲线反映了不同时间段内的供需变化,验证了算法的有效性和实用性。 适合人群:从事能源系统优化、智能算法应用的研究人员和技术开发者。 使用场景及目标:适用于需要进行能源系统优化调度的场景,特别是涉及多方利益协调的问题。目标是找到光伏电价、充电桩电价和电网电价的最佳组合,使得三方利益达到最优平衡。 其他说明:建议在调试过程中关注特定时段的电价突变,适当调整参数如社会认知系数和社会学习因子,以获得更好的收敛效果。此外,初始粒子的位置选择对收敛速度有很大影响,推荐采用高斯扰动等方法进行初始化。

    WY02锥齿轮的加工工艺规程及工时定额计算 课程设计说明书.docx

    WY02锥齿轮的加工工艺规程及工时定额计算 课程设计说明书.docx

    项目管理制度范文.docx

    项目管理制度范文.docx

Global site tag (gtag.js) - Google Analytics