SSM实现多数据源

解决的问题:动态的控制数据源。这个请求可能要查数据库甲,下一个请求可能要查数据库乙。
涉及到的知识点:spring的AbstractRoutingDataSource,mybatis的getConnection,ThreadLocal,spring-aop
纯粹是一个demo,用于笔者的学习记录:

目录截图:
SSM实现多数据源_第1张图片SSM实现多数据源_第2张图片
 

//mapper类
public interface UserMapper {
    User select(int id);
}

//实体类
public class User {
    private int id;
    private String name;
    private String sex;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

//Service类使用mapper
@Service("servicer")
public class Servicer{
    @Autowired
    private UserMapper userMapper;

    public User getUser(int id,String flag){
        return userMapper.select(id);
    }
}

//Test类
public class Test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("testroutingdatasource/spring.xml");
        Servicer servicer = (Servicer) context.getBean("servicer");
        User user = servicer.getUser(2,"one");
        System.out.println(user.getName());
        User u = servicer.getUser(1,"two");
    }
}

重要的类:
 

//切面类,在哪些方法执行之前切换数据源
@Aspect
@Component
public class AspectDataSource {
    @Pointcut("execution(* testroutingdatasource.servicer.Servicer.*(..))")
    public void pointcut(){}

    @Before("pointcut()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("设置标签");
        Object[] args = joinPoint.getArgs();
        String s = (String) args[1];
        RequestContext.set(s);
    }

}

//动态数据源核心类,在注入数据源之前动手脚
public class MyRoutingDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        //RPC请求时会在ThreadLocal里面存放请求上下文,
        // RPC请求可使用此种方法获得参数来判断用哪一个数据源
        //Object[] args = RpcContext.getContext().getArguments();
        return RequestContext.get();
    }
}

//ThreadLocal类,在一个地方保存参数,要用的时候再获得参数,也就是传递上下文信息
public class RequestContext {
    static ThreadLocal local = new ThreadLocal();

    public static void set(String s){
        local.set(s);
    }

    public static String get(){
        return local.get();
    }

    public static void clear(){
        local.remove();
    }
}

配置文件:

mapper.xml文件





    
        
        
        
        
    

    

mybaits配置文件
 




    
        
        
    


spring配置文件




    
    
        
        
        
    

    
    
        
        
        
        
    

    
    
        
        
        
        
    

    
    
        
    

    
    
    
    


    
    
    
        
        
            
                
                
            
        
    

pom文件:
 


    
    
    
      org.mybatis
      mybatis-spring
      1.3.2
    
    
      org.springframework
      spring-context
      3.2.4.RELEASE
    
    
      org.apache.commons
      commons-dbcp2
      2.1.1
    
    
      commons-pool
      commons-pool
      1.6
    
    
      org.mybatis
      mybatis
      3.4.6
    
    
      org.springframework
      spring-jdbc
      4.3.20.RELEASE
    
    
      mysql
      mysql-connector-java
      5.1.21
    
    
      org.aspectj
      aspectjweaver
      1.6.8
    
  

遇到的问题:
1,aop不生效,首先检查切点的表达式是否正确
@Pointcut("execution(* testroutingdatasource.servicer.Servicer.*(..))")
切点表达式怎么书写链接:"https://blog.csdn.net/qq_32080243/article/details/52529811"
2,spring的配置文件里,没有加启动cglib动态代理的开关

3,版本不一致,导致装配sqlSession的时候报错:AbstractMethod错误
使用aop添加aspectjweaver依赖而不是spring-aop的依赖

你可能感兴趣的:(数据库相关)