您的位置:首页 > 编程语言 > Java开发

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

2017-04-14 00:00 966 查看
摘要: 学习工作中需要多数据源的链接与动态切换,故练习之,并记录下来;

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中



将数据源放于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/



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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  springboot 多数据源