结合Spring实现数据库读写分离

**数据库配置为一个主库 多个从库 主库用于写操作 从库只读操作 
读写分离实现即为配置两个数据源,一个用于读写 连接主库 假设为ds_wr,一个用于只读 连接从库 假设为ds_r。

对数据库读操作时,操作ds_r数据源。 
对数据源写操作时,操作ds_wr数据源。

读写分离可以有两种实现方式

第一种

写两套mappper 
mapper写两套 一套用于读写 一套用于只读 **

      
          
          
          
          
      
      
          
          
          
          
      
      
          
          
      
      
          
          
      

dao1包中mapper是读写方法 对应xml文件在mapping1文件夹中 
dao2包中mapper是只读方法 对应xml文件在mapping2文件夹中

    User user = userMapper2.get(1);  
    user.setName("Susan")  
    userMapper1.update(user);  

第二种

通过实现AbstractRoutingDataSource类来动态管理数据源,本篇博客主要讲这部分内容

利用面向切面思维,每一次进入service方法前,选择数据源

首先pom.xml中添加依赖

      
      
        org.aspectj  
        aspectjrt  
        1.7.4  
      
              
                org.aspectj  
                aspectjweaver  
                1.7.4  
              

实现AbstractRoutingDataSource类 作为数据源

    package com.ifeng.auto.we_provider.common.db;  

    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;  

    /** 
     * Created by Terry on 2016/7/23. 
     */  
    public class DynamicDataSource extends AbstractRoutingDataSource {  

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

    }  

用ThreadLcoal管理当前数据源

    package com.ifeng.auto.we_provider.common.db;  

    public class DynamicDataSourceHolder {  
        public static final ThreadLocal holder = new ThreadLocal();  

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

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

用注解的形式实现AOP管理数据源

    package com.ifeng.auto.we_provider.annotation;  

    import java.lang.annotation.ElementType;  
    import java.lang.annotation.Retention;  
    import java.lang.annotation.RetentionPolicy;  
    import java.lang.annotation.Target;  

    @Retention(RetentionPolicy.RUNTIME)  
    @Target(ElementType.METHOD)  
    public @interface DataSource {  
        String value();  
    }  

切面类

    package com.ifeng.auto.we_provider.common.proxy;  


    import com.ifeng.auto.we_provider.annotation.DataSource;  
    import com.ifeng.auto.we_provider.common.db.DynamicDataSourceHolder;  
    import org.aspectj.lang.JoinPoint;  
    import org.aspectj.lang.reflect.MethodSignature;  

    import java.lang.reflect.Method;  

    /** 
     * Created by Terry on 2016/7/23. 
     */  
    public class DataSourceAspect {  
        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();  
            Class[] parameterTypes = ((MethodSignature) point.getSignature())  
                    .getMethod().getParameterTypes();  
            try {  
                Method m = classz.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();  
            }  
        }  
    }  

将注解放在service实现类的方法前,自动设置当前数据源为注解中数据源。

接下来配置aop以及数据源。

mybatis.xml

      
      
          
          

          
          
              
              
              
              

              
              
              
              

              
              

              
              

              
              

              
              
              
              
          
          
              
              
              
              

              
              
              
              

              
              

              
              

              
              

              
              
              
              
          

          
              
                  
                      
                      
                      
                      
                  

              
              
          

          
          
              
              
              
              
          

          
              
          

          
          
          
          
          
          
          
          

          
          
              
              
          

      

在service实现类中

    @DataSource("write")  
    public void savetag(UserTag userTag) {  
        userTagMapper.addUserTag(userTag);  
    }  
    @DataSource("read")  
    public UserTag getUserTagByUUID(String uuid) {  
        return userTagMapper.getUserTagByUUID(uuid);  
    }  

至此 读写分离实现

你可能感兴趣的:(常见问题库)