`
dragonsoar
  • 浏览: 206732 次
  • 性别: 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的分库...

    外加热强制循环蒸发器装配图(CAD).rar

    外加热强制循环蒸发器装配图(CAD).rar

    数控车床纵向进给系统设计.zip

    数控车床纵向进给系统设计.zip

    vault_side_off_ominous.png

    j

    爬虫 bangumi名称和评论数

    爬虫 bangumi名称和评论数

    基于SpringBoot的垃圾分类回收系统(源码+数据库+万字文档)526

    基于SpringBoot的垃圾分类回收系统,系统包含两种角色:管理员、用户主要功能如下。 【用户功能】 首页:浏览垃圾分类回收系统信息。 个人中心:管理个人信息,查看历史记录和订单状态。 运输管理:查看运输信息,垃圾回收的时间和地点。 公告管理:阅读系统发布的相关通知和公告。 垃圾回收管理:查看垃圾回收的信息,回收类型和进度。 垃圾出库申请管理:提交和查看垃圾出库申请的状态。 【管理员功能】 首页:查看垃圾分类回收系统。 个人中心:管理个人信息。 管理员管理:审核和管理注册管理员用户的信息。 用户管理:审核和管理注册用户的信息。 运输管理:监管和管理系统中的运输信息。 公告管理:发布、编辑和删除系统的通知和公告。 垃圾回收管理:监管和管理垃圾回收的信息。 垃圾出库申请管理:审批和管理用户提交的垃圾出库申请。 基础数据管理:管理系统的基础数据,运输类型、公告类型和垃圾回收类型。 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue 后端技术:SpringBoot 三、运行环境 操作系统:Windows、macOS都可以 JDK版本:JDK1.8以上都可以 开发工具:IDEA、Ecplise、Myecplise都可以 数据库: MySQL5.7以上都可以 Maven:任意版本都可以

    这篇文章是台湾大学(NTU)计算机科学与信息工程系(CSIE)2021年秋季学期算法设计与分析课程的第一份作业(Homework#1)的具体要求和题目描述 以下是主要内容的总结:

    内容概要:本文档是台湾大学计算机科学与信息工程系2021年秋季学期《算法设计与分析》课程的第一次作业(Homework#1)。作业包含四道编程题和三道手写题,旨在考察学生对算法设计和分析的理解与应用能力。编程题涉及汉诺塔、数组计算、矩形点对、糖果分配等问题;手写题涵盖渐近符号证明、递归方程求解、幽灵腿游戏优化、不公平的卢卡斯问题等。文档详细描述了每个问题的具体要求、输入输出格式、测试用例以及评分标准。此外,还提供了编程技巧和注意事项,如避免延迟提交、正确引用资料、处理大输入文件等。 适合人群:具备一定编程基础的本科生或研究生,特别是修读过或正在修读算法设计与分析相关课程的学生。 使用场景及目标:①帮助学生巩固课堂所学的算法理论知识;②通过实际编程练习提高解决复杂问题的能力;③为后续更深入的学习和研究打下坚实的基础。 其他说明:此作业强调团队合作和个人独立思考相结合的重要性,鼓励学生在讨论后用自己的语言表达解决方案,并注明参考资料。对于编程题,特别提醒学生注意输入文件可能较大,建议采取适当的优化措施以确保程序运行效率。

    基于SpringBoot的铁路订票管理系统(源码+数据库+万字文档+ppt)528

    基于SpringBoot的铁路订票管理系统,系统包含两种角色:管理员、用户主要功能如下。 【用户功能】 首页:浏览铁路订票管理系统的主要信息。 火车信息:查看火车的相关信息,包括车次、出发地、目的地和票价等。 公告资讯:阅读系统发布的相关通知和资讯。 后台管理:进行系统首页、个人中心、车票预订管理、车票退票管理等操作。 个人中心:管理个人信息,查看订单历史记录等。 【管理员功能】 首页:查看铁路订票管理系统。 个人中心:修改密码、管理个人信息。 用户管理:审核和管理注册用户的信息。 火车类型管理:管理系统中的火车类型信息。 火车信息管理:监管和管理系统中的火车信息,添加、编辑、删除等。 车票预订管理:处理用户的车票预订请求。 车票退票管理:处理用户的车票退票请求。 系统管理:管理系统的基本设置,公告资讯、关于我们、系统简介和轮播图管理。 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue 后端技术:SpringBoot 三、运行环境 操作系统:Windows、macOS都可以 JDK版本:JDK1.8以上都可以 开发工具:IDEA、Ecplise、Myecplise都可以 数据库: MySQL5.7以上都可以 Maven:任意版本都可以

    塑料架注射模具设计.rar

    塑料架注射模具设计.rar

    基于json文件数据驱动的的接口测试框架.zip

    基于json文件数据驱动的的接口测试框架

    铁丝缠绕包装机设计-缠绕盘设计.rar

    铁丝缠绕包装机设计-缠绕盘设计.rar

    Linux操作系统及常用命令详解.zip

    linux

    圆柱体相贯线焊接专机工作台设计.rar

    圆柱体相贯线焊接专机工作台设计.rar

    硬币分拣机设计.rar

    硬币分拣机设计.rar

    【机器学习与数据挖掘】行业级机器学习软件开发经验与教训:从LIBSVM和LIBLINEAR看算法部署及软件设计挑战

    内容概要:本文探讨了开发行业级机器学习和数据挖掘软件的经验与教训,指出当前研究界与工业界之间的脱节问题。作者分享了开发LIBSVM和LIBLINEAR的经验,强调了用户需求的重要性。大多数用户并非机器学习专家,期望简单易用的工具来获得良好结果。文章还详细介绍了支持向量机(SVM)的实际应用案例,包括数据预处理(如特征缩放)、参数选择等步骤,并提出了为初学者设计的简易流程。此外,作者讨论了在设计机器学习软件时应考虑的功能选择、选项数量、性能优化与数值稳定性等问题,强调了软件开发与实验代码的区别以及鼓励研究人员参与高质量软件开发的重要性。 适合人群:对机器学习软件开发感兴趣的科研人员、工程师及从业者,尤其是那些希望了解如何将学术研究成果转化为实际可用工具的人士。 使用场景及目标:①帮助非机器学习专家的用户更好地理解和使用机器学习方法;②指导开发者在设计机器学习软件时考虑用户需求、功能选择、性能优化等方面的问题;③促进学术界与工业界之间的合作,推动高质量机器学习软件的发展。 其他说明:本文不仅提供了具体的开发经验和技巧,还呼吁建立激励机制,鼓励更多研究人员投入到机器学习软件的开发中,以解决当前存在的研究与应用脱节的问题。

    pandas学习代码,jypyter格式

    一天入门pandas代码

    joblib-0.12.0-py2.py3-none-any.whl

    该资源为joblib-0.12.0-py2.py3-none-any.whl,欢迎下载使用哦!

Global site tag (gtag.js) - Google Analytics