本人是根据别人博客和自己见解进行一个整合,直接代码上
<!-- 默认是 读取数据源 --> <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); } }
以上基本就完成所有的读写分离 如有不对,请留言和更正