springmvc+mybatis+mysql 实现读写分离

来源:互联网 发布:java试题库及答案 编辑:程序博客网 时间:2024/05/16 13:56

上一篇文章实现了mysql的主从同步,所试着在springmcv中实现读写分离。
主要方式其实就是通过spingAop控制方法访问的数据库表,
由于我是基于前几文章的项目来实现的,所以项目搭建和jar都已经有了直接开始写实现,
第一步:sping配置文件
1,多数据源配置:
这里写图片描述
配置了两个一个读一个写:所以beanName分别为:readDataSource和writeDataSource数据源的ip分别为mysql主从的ip;
dataSource bean是自己用aop的方式写路由控制器,负责通过不同的key加载不同的数据源给最终调用数据库表操作的方法。
这个dataSource 最终的事物控制还是由
这里写图片描述来控制,和一般的事物没什么却别;
现在看看路由的实现:

package com.java.spring.util.aspect;import java.lang.reflect.Method;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.stereotype.Component;import com.java.spring.util.dynamicDataSource.DataSource;import com.java.spring.util.dynamicDataSource.DynamicDataSourceHolder;/*** @author 作者:zhaofq* @version 创建时间:2017年4月14日 下午4:24:36* 类说明:在访问每个方法之前会进行拦截调用,其目的就是通过方法调用key来加载不同的数据源*/public class DataSourceAspect {      //@Pointcut("execution(* com.apc.cms.service.*.*(..))")      public void pointCut(){};    //  @Before(value = "pointCut()")     public void before(JoinPoint point)        {            Object target = point.getTarget();            System.out.println(target.toString());            String method = point.getSignature().getName();            System.out.println(method);            Class<?>[] classz = target.getClass().getInterfaces();            Class<?>[] parameterTypes = ((MethodSignature) point.getSignature())                    .getMethod().getParameterTypes();            try {                Method m = classz[0].getMethod(method, parameterTypes);                System.out.println(m.getName());                if (m != null && m.isAnnotationPresent(DataSource.class)) {                    DataSource data = m.getAnnotation(DataSource.class);                     //加载已经在内存中数据源,                    DynamicDataSourceHolder.putDataSource(data.value());                }            } catch (Exception e) {                e.printStackTrace();            }        }}
package com.java.spring.util.dynamicDataSource;/*** @author 作者:zhaofq* @version 创建时间:2017年4月14日 下午4:22:41* 类说明*/public class DynamicDataSourceHolder {        public static final ThreadLocal<String> holder = new ThreadLocal<String>();        public static void putDataSource(String name) {            holder.set(name);        }        public static String getDataSouce() {            return holder.get();        }}
package com.java.spring.util.dynamicDataSource;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/*** @author 作者:zhaofq* @version 创建时间:2017年4月14日 下午4:10:00* 类说明*/@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface DataSource {    String value();}
package com.java.spring.util.dynamicDataSource;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/*** @author 作者:zhaofq* @version 创建时间:2017年4月14日 下午4:21:59* 类说明*/public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {         return DynamicDataSourceHolder.getDataSouce();    }}

对应的几个类,完成实现,、
调用的方式:已经控制到了业务从sping配置就能找到
这里写图片描述
所只需要在操作数据方式的时候注解就可以:
这里写图片描述
这里写图片描述

0 0
原创粉丝点击