</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); } }以上基本就完成所有的读写分离 如有不对,请留言和更正
