spring+ibatis实现读写分离(分享我的开源项目)

先吐槽下博客园,每天都推荐水帖不说,正经的分享技术的博客还他妈的不让上首页,我在那里投入了那么多汗水,什么垃圾东西。

spring+ibatis实现读写分离

  • 特点

    无缝结合spring+ibatis,对于程序员来说,是透明的

    除了修改配置信息之外,程序的代码不需要修改任何东西

    支持spring的容器事务

  • 规则:
    1. 基于spring配置的容器事务
    2. 读写事务到主库
    3. 只读事务到从库
    4. 如果没有配置事务,更新语句全部到主库,查询语句均衡到从库

      源码地址

      qq讨论群:261502547

  • 快速入门

    maven依赖

<dependency>
    <groupId>org.springmore</groupId>
    <artifactId>springmore-core</artifactId>
    <version>1.0.0</version>
</dependency>

dataSource配置(applicationContext.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"
    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
        ">
    <!-- C3P0连接池配置 -->
    <bean id="master" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="jdbcUrl">
            <value>jdbc:mysql://192.168.1.246:3306/db1</value>
        </property>
        <property name="user">
            <value>ysb</value>
        </property>
        <property name="password">
            <value>ysb</value>
        </property>
        <property name="initialPoolSize">
            <value>20</value>
        </property>
        <property name="minPoolSize">
            <value>20</value>
        </property>
        <property name="maxPoolSize">
            <value>200</value>
        </property>
        <property name="maxIdleTime">
            <value>255000</value>
        </property>
    </bean>

    <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="jdbcUrl">
            <value>jdbc:mysql://192.168.1.246:3306/db2</value>
        </property>
        <property name="user">
            <value>ysb</value>
        </property>
        <property name="password">
            <value>ysb</value>
        </property>
        <property name="initialPoolSize">
            <value>20</value>
        </property>
        <property name="minPoolSize">
            <value>20</value>
        </property>
        <property name="maxPoolSize">
            <value>200</value>
        </property>
        <property name="maxIdleTime">
            <value>255000</value>
        </property>
    </bean>

    <bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="jdbcUrl">
            <value>jdbc:mysql://192.168.1.246:3306/db3</value>
        </property>
        <property name="user">
            <value>ysb</value>
        </property>
        <property name="password">
            <value>ysb</value>
        </property>
        <property name="initialPoolSize">
            <value>20</value>
        </property>
        <property name="minPoolSize">
            <value>20</value>
        </property>
        <property name="maxPoolSize">
            <value>200</value>
        </property>
        <property name="maxIdleTime">
            <value>255000</value>
        </property>
    </bean>

    <bean id="dataSource" class="org.springmore.core.datasource.DynamicDataSource">
        <property name="master" ref="master" />
        <property name="slaves">
            <list>
                <ref bean="dataSource2"/>
                <ref bean="dataSource3"/>
            </list>
        </property>
    </bean>
</beans>

整合mybatis配置(applicationContext.xml中)

    <!-- ibatis3 工厂类 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:sqlMapConfig.xml" />
    </bean>
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

    <bean id="dynamicSqlSessionTemplate" class="org.springmore.core.datasource.DynamicSqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionTemplate" />
    </bean>

事务配置(applicationContext.xml中)

    <!-- 定义单个jdbc数据源的事务管理器 -->
    <bean id="transactionManager"
        class="org.springmore.core.datasource.DynamicDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 以 @Transactional 标注来定义事务  -->
    <tx:annotation-driven transaction-manager="transactionManager"
        proxy-target-class="true" />        

    <!-- 配置事务的传播特性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="delete*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="update*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="proc*" propagation="REQUIRED" read-only="false"
                rollback-for="Exception" />
            <tx:method name="select*" read-only="true" />
            <tx:method name="*" read-only="false" />
            <!-- <tx:method name="*" read-only="true" /> -->
        </tx:attributes>
    </tx:advice>
    <!-- 那些类的哪些方法参与事务 -->
    <aop:config>
        <aop:pointcut id="allManagerMethod" expression="execution(* org.springmore.core.dao..*(..))" />
        <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice" />
    </aop:config>

dao代码示例:

@Repository("UserMapperImpl")
public class UserMapperImpl implements UserMapper{

    @Autowired
    private DynamicSqlSessionTemplate sqlSessionTemplate;

    //从库
    public List<User> selectByUserNameAndPwd(User user) {
        return sqlSessionTemplate.selectList("selectByUserNameAndPwd", user);
    }

    //主库
    public void insert(User user) {
        sqlSessionTemplate.insert("insert", user);
    }
}
时间: 2024-10-27 04:59:19

spring+ibatis实现读写分离(分享我的开源项目)的相关文章

分享我的开源项目-springmore

概述 核心意义 提供一个项目框架:spring+mybatis+springMVC 提供最佳项目示例(工作中常见的功能) 封装一般工具类如FileUtil,DateUtil,StringUtil,FTPUtil等 封装复杂组件,如redis,mina,netty 欢迎加入springmore讨论qq群:261502547 个人QQ: 370493945 非诚勿扰 github地址:https://github.com/tangyanbo/springmore springmore-core组件

基于spring的数据库读写分离

背景: Spring读写分离是大家都比较常见并一直在使用的技术. 本博文再次对其进行阐述,一方面是为了更好的分享给大伙,一方面也是对最近做"XXX系统"遇到的问题做一次整理.方便大家以后遇到类似问题可以很快解决.技术实现: 1.多数据源配置.配置包括一个主库master_dataSource,一个个从库slave_dataSource. 数据源托管给tomcat控制,系统通过jndi方式寻找.配置内容如下: <beans profile="production"

使用Spring实现MySQL读写分离

1. 为什么要进行读写分离 大量的JavaWeb应用做的是IO密集型任务, 数据库的压力较大, 需要分流 大量的应用场景, 是读多写少, 数据库读取的压力更大 一个很自然的思路是使用一主多从的数据库集群: 一个是主库,负责写入数据:其它都是从库,负责读取数据. 主从库数据同步. mysql原生支持主从复制 mysql主(称master)从(称slave)复制的原理:1.master将数据改变记录到二进制日志(bin log)中,  这些记录叫binary log events2.slave将ma

Spring 实现数据库读写分离

现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库.Master库负责数据更新和实时数据查询,Slave库当然负责非实时数据查询.因为在实际的应用中,数据库都是读多写少(读取数据的频率高,更新数据的频率相对较少),而读取数据通常耗时比较长,占用数据库服务器的CPU较多,从而影响用户体验.我们通常的做法就是把查询从主库中抽取出来,采用多个从库,使用负载均衡,减轻每个从库的查询压力. 采用读写分离技术的目标:有效减轻Master库的压力,又可以

spring AbstractRoutingDataSource 实现读写分离

spring有提供AbstractRoutingDataSource类来实现数据源的动态切换,用来实现读写分离也自然没什么问题了. 实现原理:扩展Spring的AbstractRoutingDataSource抽象类(该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上.) 从AbstractRoutingDataSource的源码中: public abstract class AbstractRoutingDataSource 

使用Spring+MySql实现读写分离(二)spring整合多数据库

紧接着上一章,因为现在做的项目还是以spring为主要的容器管理框架,所以写以下spring如何整合多个数据源. 1. 背景 我们一般应用对数据库而言都是"读多写少",也就说对数据库读取数据的压力比较大,有一个思路就是说采用数据库集群的方案, 其中一个是主库,负责写入数据,我们称之为:写库: 其它都是从库,负责读取数据,我们称之为:读库: 那么,对我们的要求是: 1. 读库和写库的数据一致: 2. 写数据必须写到写库: 3. 读数据必须到读库: 2. 方案 解决读写分离的方案有两种:应

Spring 实现数据库读写分离(转)

现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库.Master库负责数据更新和实时数据查询,Slave库当然负责非实时数据查询.因为在实际的应用中,数据库都是读多写少(读取数据的频率高,更新数据的频率相对较少),而读取数据通常耗时比较长,占用数据库服务器的CPU较多,从而影响用户体验.我们通常的做法就是把查询从主库中抽取出来,采用多个从库,使用负载均衡,减轻每个从库的查询压力. 采用读写分离技术的目标:有效减轻Master库的压力,又可以

spring手写读写分离

一,原理 利用spring提供的AbstractRoutingDataSource的determineCurrentLookupKey,lookupkey路由方法决定DataSource. 二,步骤 准备拦截器,用于拦截mybatis的请求 1 @Intercepts({@Signature(type = Executor.class,method = "update", args = {MappedStatement.class,Object.class}), 2 @Signatur

Mybatis+Spring实现Mysql读写分离

使用spring AbstractRoutingDatasource实现多数据源 public class DynamicDataSource extends AbstractRoutingDataSource { //写数据源 private Object writeDataSource; //读数据源 private Object readDataSource; @Override public void afterPropertiesSet() { Assert.isNull(writeD