基于springAop 打造的应用层的 spring+mybatis+mysql 读写分离

本人是根据别人博客和自己见解进行一个整合,直接代码上
<!-- 默认是 读取数据源 -->
<bean id="dataSourceWR" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="${jdbc_driverClassName}"/>
    <property name="url" value="${jdbc_url_r}"/>
    <property name="username" value="${jdbc_username_r}"/>
    <property name="password" value="${jdbc_password_r}"/>
    <property name="maxIdle" value="${jdbc_maxIdle_r}"/>
    <!-- 可以在这个池中同时被分配的有效连接数的最大值,如设置为负数,则不限制 -->
    <property name="maxTotal" value="${jdbc_maxTotal_r}"/>
    <property name="maxWaitMillis" value="${jdbc_maxWaitMillis_r}"/>
    <property name="removeAbandonedOnMaintenance" value="${jdbc_removeAbandoned_r}"/>
    <property name="removeAbandonedTimeout" value="${jdbc_removeAbandonedTimeout_r}"/>
    <property name="minIdle" value="${jdbc_minIdle_r}"/>
</bean>

<!-- 写数据源 -->
<bean id="dataSourceW" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="${jdbc_driverClassName}"/>
    <property name="url" value="${jdbc_url_w}"/>
    <property name="username" value="${jdbc_username_w}"/>
    <property name="password" value="${jdbc_password_w}"/>
    <property name="maxIdle" value="${jdbc_maxIdle_w}"/>
    <!-- 可以在这个池中同时被分配的有效连接数的最大值,如设置为负数,则不限制 -->
    <property name="maxTotal" value="${jdbc_maxTotal_w}"/>
    <property name="maxWaitMillis" value="${jdbc_maxWaitMillis_w}"/>
    <property name="removeAbandonedOnMaintenance" value="${jdbc_removeAbandoned_w}"/>
    <property name="removeAbandonedTimeout" value="${jdbc_removeAbandonedTimeout_w}"/>
    <property name="minIdle" value="${jdbc_minIdle_w}"/>

</bean>

<!-- 动态数据源 -->
<bean id="dataSource" class="com.irongyan.client.datasource.DynamicDataSource">
    <!-- 通过key-value关联数据源 -->
    <property name="targetDataSources">
        <map>
            <entry value-ref="dataSourceWR" key="dataSourceWR"></entry>
            <entry value-ref="dataSourceW" key="dataSourceW"></entry>
        </map>
    </property>
    <property name="defaultTargetDataSource" ref="dataSourceWR" />
</bean>

<!-- mybatis文件配置,扫描所有mapper文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
      p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml"
      p:mapperLocations="classpath:mapper/*.xml" />



<!-- 开启aop -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean class="com.irongyan.client.aop.DaoAopDynamicDB"/>

以上配置 整合spring +mybaits  ,所有配置就这样 接下来就是代码的实现

package com.irongyan.client.datasource;

/**
 *@Author: yw
 *@Desciption:  管理数据源的切换
 *@Date:18:00 2018/5/17
 */
public class DBContextHolder {
    private static  ThreadLocal<String> contextHolder=new ThreadLocal<>();
    public static String DBR="dataSourceKeyR";
    public static String DBW="dataSourceWR";
    public void setDBType(String key){
        contextHolder.set(key);
    }
    public String getDBType(){
        String db = contextHolder.get();
        if(db==null){
            return DBR;//默认是是读写的数据源
        }
        return db;
    }


    public void removeDB(){
        contextHolder.remove();
    }

}

package com.irongyan.client.datasource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
 *@Author: yw
 *@Desciption: 动态选择数据源根据对应的key 获取不同的数据源
 *@Date:18:02 2018/5/17
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return new DBContextHolder().getDBType();
    }
}

切入点 :

package com.irongyan.client.aop;

import com.irongyan.client.datasource.DBContextHolder;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 *@Author: yw
 *@Desciption:切入点是dao, 当有操作dao层的时候 根据操作的数据的类型进行切换读写的数据源,
 *@Date:18:05 2018/5/17
 */
@Aspect
public class DaoAopDynamicDB {
    //dao 下面的所有add方法
    @Pointcut("execution(* *..*Dao*.add*(*,..))")
    public void doAdd(){}
    //
    @Pointcut("execution(* *..*Dao*.update*(*,..))")
    public void doUpdate(){}

    @Pointcut("execution(* *..*Dao*.delete*(*,..))")
    public void doDel(){}
    @Pointcut("execution(* *..*Dao*.query*(*,..))")
    public void doQuery(){}
    @Pointcut("execution(* com.irongyan.client.dao.find*.*(..))")
    public void doFind(){}
    写数据库
    @Before(value="doAdd()")
    public void dynamicDataSourceDoAddW(){
        System.out.println("设置数据源为写:" + DBContextHolder.DBW);
         new DBContextHolder().setDBType(DBContextHolder.DBW);
    }
    @Before(value="doDel()")
    public void dynamicDataSourceDoDelW(){
        System.out.println("设置数据源为写:" + DBContextHolder.DBW);
        new DBContextHolder().setDBType(DBContextHolder.DBW);
    }
    @Before(value="doUpdate()")
    public void dynamicDataSourcedoUpdateW(){
        System.out.println("设置数据源为写:" + DBContextHolder.DBW);
        new DBContextHolder().setDBType(DBContextHolder.DBW);
    }
    ///只读数据库
    @Before(value="doQuery()")
    public void dynamicDataSourceDoQueryR(){
        System.out.println(">>>>>>>>>>>>>>>>设置数据源为读:" + DBContextHolder.DBR);
        new DBContextHolder().setDBType(DBContextHolder.DBW);
    }
    @Before(value="doFind()")
    public void dynamicDataSourceDoFindR(){
        System.out.println(">>>>>>>>>>>>>>>>设置数据源为读:" + DBContextHolder.DBR);
        new DBContextHolder().setDBType(DBContextHolder.DBW);
    }
}

以上基本就完成所有的读写分离 如有不对,请留言和更正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值