运用springboot+mybatis 实现动态多数据源

1.获取数据源 DynamicDataSource.java

package com.test.data.config;

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

/**
 * 获取数据源
 * Created by guanguan on 2017/8/22.
 */
public class DynamicDataSource extends AbstractRoutingDataSource{


    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataHolder.getDataSource();
    }
}

2.DynamicDataHolder.java一个自定义的操作数据源的类

package com.test.data.config;

import com.test.data.enums.DataSourceType;

/**
 * 数据源操作的类
 * Created by guanguan on 2017/8/22.
 */
public class DynamicDataHolder {


    //线程本地环境
    private static final ThreadLocal<DataSourceType> dataSources = new ThreadLocal<DataSourceType>();


    //设置数据源
    public static void setDataSources(DataSourceType dataSourceType){
        dataSources.set(dataSourceType);
    }

    //获取数据源
    public static DataSourceType getDataSource(){
        return dataSources.get();
    }


    //清除数据源
    public static void clearDataSource(){
        dataSources.remove();
    }



}

3.MyBatisConfig.java

package com.test.data.config;

import com.test.data.enums.DataSourceType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.util.HashMap;

/**
 * Created by guanguan on 2017/7/20.
 */
@Configuration
@MapperScan("com.test.data.dao")  //扫描到dao层实现mybatis的xml文件与dao层的文件进行映射绑定
public class MybatisConfig {
    


    /**
     * 创建数据源 manage
     * @return
     * @throws Exception
     */
    @Bean
    @ConfigurationProperties(prefix = "manage")  //从yml配置文件里读取,如果配置在spring路径下,可改为spring.manage
    public DataSource manageDataSource() throws Exception{
        return DataSourceBuilder.create().build();
    }


    /**
     * 创建数据源 test
     * @return
     * @throws Exception
     */
    @Bean
    @ConfigurationProperties(prefix = "test")//从yml配置文件里读取,指定配置项的前缀
    public DataSource testDataSource() throws Exception{

        return DataSourceBuilder.create().build();
    }


    /**
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Primary
    public DynamicDataSource dataSource(@Qualifier("manageDataSource") DataSource manageDataSource,
                                        @Qualifier("testDataSource") DataSource testDataSource){
        HashMap<Object,Object> targetDataSources = new HashMap<Object,Object>();
        targetDataSources.put(DataSourceType.manage,manageDataSource);
        targetDataSources.put(DataSourceType.test,testDataSource);

        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources); //该方法是继承的AbstractRoutingDataSource的方法
        dataSource.setDefaultTargetDataSource(manageDataSource); //设置默认的数据源

        return dataSource;
    }




    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mybatis/*/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }


}



//项目启动时,会运行加载该类,从yml的配置中自动分配数据源,到DynamicDataSource实体中

以上为启动是分配的多数据源,启动时将配置文件yml中的数据源配置放于DynamicDataSource中

093832_F6UK_2263272.png

将数据源放于sqlSessionFactoryBean中

4.DataSourceType.java文件,枚举,数据源的命名

package com.test.data.enums;

/**
 * Created by guanguan on 2017/8/22.
 */
public enum  DataSourceType {
    manage,test
}

4.拦截,并自动分配数据源 DataSourceAspect.java

package com.test.data.interceptor;

import com.test.data.config.DynamicDataHolder;
import com.test.data.enums.DataSourceType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * Created by guanguan on 2017/8/22.
 */
@Aspect  //aop切面拦截
@Component //组件,启动时加载
public class DataSourceAspect {


    /**
     * 在通用方法中拦截操作数据库的方法
     * @param point
     */
    @Before("execution(* com.test.data.service.Services.*(..))")
    public void setDataSourceKeyByPublic(JoinPoint point){
        String targetStr = point.getTarget().toString();
        setDataSourceKey(targetStr);
    }



    @Before("execution(* com.test.data.service.*.*.*(..))")
    public void setDataSourceKeyByPrivate(JoinPoint point){
        String targetStr = point.getTarget().toString();
        setDataSourceKey(targetStr);
    }




    private void setDataSourceKey(String targetStr){
        if(targetStr.contains("manage")){
            DynamicDataHolder.setDataSources(DataSourceType.manage);
        }else if(targetStr.contains("test")){
            DynamicDataHolder.setDataSources(DataSourceType.test);
        }
    }
}

5.application.yml文件

server:
  port: 8389


manage:
    url: jdbc:mysql://127.0.0.1/manage?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true
    username: upgrade
    password: upgrade
    driverClassName: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    validation-query: select 'x'
    test-while-idle: true
test:
    url: jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true
    username: upgrade
    password: upgrade
    driverClassName: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    validation-query: select 'x'
    test-while-idle: true

pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql




logging:
  level.com.test.data: debug

6.controller.java校验多数据源的方法,查询两个库的不同的表的数据

package com.test.data.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.test.data.model.manage.LoginLog;
import com.test.data.model.test.User;
import com.test.data.service.manage.LoginLogService;
import com.test.data.service.test.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;

/**
 * Created by guanguan on 2017/7/20.
 */
@Controller
public class controller {
    @Autowired
    UserService userService;
    @Autowired
    LoginLogService loginLogService;




    @RequestMapping("/")
    @ResponseBody
    public String index() {
     
        List<User> userList = userService.findBy(new HashMap<Object, Object>());
        List<LoginLog> loginLogList = loginLogService.findBy(new HashMap<Object, Object>());

        return JSON.toJSONString(userList)+JSON.toJSONString(loginLogList);
     }
}

7.查询结果:(由于没写前端页面展示为string的返回结果)

输入:http://localhost:8389/

211155_M1Da_2263272.png

8.pom.xml文件要加入aop依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>1.3.6.RELEASE</version>
        </dependency>

8.整个工程的布局:

见github地址:

https://github.com/gholly/springboot-multi-datasource

 

转载于:https://my.oschina.net/u/2263272/blog/879705

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值