mybatis 应用层读写分离

1.配置两个数据源到动态数据源

<bean id="dataSource" class="com.che.rw.datasource.DynamicDataSource">
    <property name="defaultTargetDataSource" ref="masterDataSource"></property>
    <property name="targetDataSources">
        <map>
            <entry key="master" value-ref="masterDataSource"></entry>
            <entry key="slave" value-ref="slaveDataSource"></entry>
        </map>
    </property>
</bean>
 
<!-- 数据源切面 -->
<bean id="dualDataSourceAspect" class="com.che.rw.aspect.DataSourceAspect">
   <property name="slaveList">
      <list>
         <value>query</value>
         <value>get</value>
         <value>find</value>
         <value>select</value>
      </list>
   </property>
   <property name="logEnable" value="false" />
</bean>

//aop 配置拦截多个mapper 包
<!-- 配置aop -->
   <aop:config>
<!--      <aop:pointcut id="pointcut1" expression="execution(* com.sfbm.carmall.service.*.*(..))" /> -->
<!--      <aop:pointcut id="pointcut2" expression="execution(* com.che.mall..service.*.*(..))" /> -->
      <aop:pointcut id="pointcut1" expression="execution(* com.sfbm.carmall..*Service.*(..))" />
      <aop:pointcut id="pointcut2" expression="execution(* com.che.mall..*Service.*(..))" />
      
      <aop:aspect id="aspect1" ref="dualDataSourceAspect"> 
         <aop:before pointcut-ref="pointcut1" method="before" />
      </aop:aspect>
      <aop:aspect id="aspect2" ref="dualDataSourceAspect"> 
         <aop:before pointcut-ref="pointcut2" method="before" />
      </aop:aspect>
   </aop:config>  

 
2.sessionFactory 和  Transactionmanager 设置为动态数据源
 
3.定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Master {
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Slave {
}
public class DynamicDataSource extends AbstractRoutingDataSource {
    public DynamicDataSource() {
    }

    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceHolder.getDataSouce();
    }
}

public class DynamicDataSourceHolder {
    private static final ThreadLocal<String> holder = new ThreadLocal();

    public DynamicDataSourceHolder() {
    }

    public static void putDataSource(String name) {
        holder.set(name);
    }

    public static String getDataSouce() {
        return (String)holder.get();
    }
}

public class DataSourceAspect {
    private List<String> slaveList;
    private boolean logEnable = false;

    public DataSourceAspect() {
    }

    public void before(JoinPoint point) {
        try {
            Object e = point.getTarget();
            String method = point.getSignature().getName();
            Class clazz = e.getClass();
            Class[] parameterTypes = ((MethodSignature)point.getSignature()).getMethod().getParameterTypes();
            Method m = clazz.getMethod(method, parameterTypes);
            if(m == null) {
                return;
            }

            String dataSourceName = "master";
            if(m.isAnnotationPresent(Master.class)) {
                dataSourceName = "master";
            } else if(m.isAnnotationPresent(Slave.class)) {
                dataSourceName = "slave";
            } else if(this.slaveList != null && !this.slaveList.isEmpty()) {
                String mName = m.getName();
                Iterator i$ = this.slaveList.iterator();

                while(i$.hasNext()) {
                    String start = (String)i$.next();
                    if(mName.startsWith(start)) {
                        dataSourceName = "slave";
                        break;
                    }
                }
            }

            DynamicDataSourceHolder.putDataSource(dataSourceName);
            if(this.logEnable) {
                System.out.println(dataSourceName);
            }
        } catch (Exception var11) {
            var11.printStackTrace();
        }

    }

    public void setSlaveList(List<String> slaveList) {
        this.slaveList = slaveList;
    }

    public void setLogEnable(boolean logEnable) {
        this.logEnable = logEnable;
    }
}

3.配置spring aop ,扫描的包为mybatis mapper 文件路径  在mapper方法执行之前 执行前置通知,动态切换数据源
 
 
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值