最近项目有一个非解决不可的问题,我们的项目中的用户表是用的自己库的数据,但是这些数据都是从一个已有库中迁过来的,所以用户信息都是在那个项目里面维护,自然而然我们项目不提供用户注册功能,这就有个问题,如何解决数据迁移的问题,总不能我每次都手动导数据吧,所以我决心写一个接口把那个库中的用户信息同步我们的库中去。

  这又涉及到一个问题,如何在一个服务中连接两个库,在网上搜索了一番,算是把问题解决了,现将多数据源demo代码贴出来,先看一下我的目录结构

controller、mapper、pojo、service这几个常见的业务逻辑包我们放到最后看,先看一下util包里面的类

DatabaseType

/**
* 采用枚举的方法列出所有的数据源key(常用数据库名称来命名)
* 数据源个数和数据库个数保持一致
*/
public enum DatabaseType {
mytestdb,mytestdb2
}

这里就是列出所有的数据源,相当于定义了两个常量,便于统一维护

DynamicDataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源(需要继承AbstractRoutingDataSource)
*/
public class DynamicDataSource extends AbstractRoutingDataSource { //定义一个线程安全的DatabaseType容器
private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<DatabaseType>(); public static DatabaseType getDatabaseType(){
return contextHolder.get();
} public static void setDatabaseType(DatabaseType type) {
contextHolder.set(type);
}
//获取当前线程的DatabaseType
protected Object determineCurrentLookupKey() {
return getDatabaseType();
}
}

在这里创建一个动态数据源的类,定义了DatabaseType的get和set方法,用getDatabaseType()获得一个当前线程的DatabaseType来重写determineCurrentLookupKey()方法。

最后来看一下config包下面的类

MybatisConfig

import java.util.HashMap;
import java.util.Map;
import java.util.Properties; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.fiberhome.ms.multiDataSource.util.DatabaseType;
import com.fiberhome.ms.multiDataSource.util.DynamicDataSource; /**
* springboot集成mybatis的基本入口
* 1) 获取数据源
* 2)创建数据源
* 3)创建SqlSessionFactory
* 4)配置事务管理器,除非需要使用事务,否则不用配置
*/
@Configuration
public class MybatisConfig implements EnvironmentAware { private Environment environment; public void setEnvironment(final Environment environment) {
this.environment = environment;
} /**
* 创建数据源,从配置文件中获取数据源信息
*/
@Bean
public DataSource testDataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", environment.getProperty("jdbc.driverClassName"));
props.put("url", environment.getProperty("jdbc.url"));
props.put("username", environment.getProperty("jdbc.username"));
props.put("password", environment.getProperty("jdbc.password"));
return DruidDataSourceFactory.createDataSource(props);
} @Bean
public DataSource test1DataSource() throws Exception {
Properties props = new Properties();
props.put("driverClassName", environment.getProperty("jdbc2.driverClassName"));
props.put("url", environment.getProperty("jdbc2.url"));
props.put("username", environment.getProperty("jdbc2.username"));
props.put("password", environment.getProperty("jdbc2.password"));
return DruidDataSourceFactory.createDataSource(props);
} /**注入数据源
*/
@Bean
public DynamicDataSource dataSource(@Qualifier("testDataSource")DataSource testDataSource, @Qualifier("test1DataSource")DataSource test1DataSource) {
Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
targetDataSources.put(DatabaseType.mytestdb, testDataSource);
targetDataSources.put(DatabaseType.mytestdb2, test1DataSource); DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
dataSource.setDefaultTargetDataSource(testDataSource);// 默认的datasource设置为myTestDbDataSource return dataSource;
} /**
* 根据数据源创建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(@Qualifier("testDataSource") DataSource testDataSource,
@Qualifier("test1DataSource") DataSource test1DataSource) throws Exception{
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
fb.setDataSource(this.dataSource(testDataSource, test1DataSource));
fb.setTypeAliasesPackage("com.fiberhome.ms.multiDataSource");// 指定基包
fb.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));//
return fb.getObject();
} /**
* 配置事务管理器
*/
@Bean
public DataSourceTransactionManager testTransactionManager(DynamicDataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
} }

上面这段代码在创建数据源DataSource实例时采用的是@bean注解注入的方式,使其成为受spring管理的bean。在后面的方法把两个DataSource作为参数传入,可以看到用了@Qualifier注解,加这个注解是为了解决多个实例无法直接装配的问题,在这里有两个DataSource类型的实例,需要指定名称装配。

还有数据源配置文件

application.properties

#the first datasource
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
jdbc.username = root
jdbc.password = 123456 #the second datasource
jdbc2.driverClassName = com.mysql.jdbc.Driver
jdbc2.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8
jdbc2.username = root
jdbc2.password = 123456

说完了关键的通用代码,再来看看如何在业务代码中使用

UserServiceImpl

import com.fiberhome.ms.multiDataSource.mapper.UserMapper;
import com.fiberhome.ms.multiDataSource.pojo.User;
import com.fiberhome.ms.multiDataSource.service.UserService;
import com.fiberhome.ms.multiDataSource.util.DatabaseType;
import com.fiberhome.ms.multiDataSource.util.DynamicDataSource;
@Service
public class UserServiceImpl implements UserService { @Autowired
private UserMapper userMapper; @Override
public List<User> getTestUser() {
//设置数据源
DynamicDataSource.setDatabaseType(DatabaseType.mytestdb);
return userMapper.findUser();
} @Override
public List<User> getTest1User() {
//设置数据源
DynamicDataSource.setDatabaseType(DatabaseType.mytestdb2);
return userMapper.findUser();
} }

在service层的实现类中设置数据源即可指定哪个mapper接口使用哪个数据源,这样就OK了。剩下的业务代码很简单就不贴了。。。

springboot整合mybatis的多数据源解决办法的更多相关文章

  1. SpringBoot整合Mybatis之项目结构、数据源

    已经有好些日子没有总结了,不是变懒了,而是我一直在奋力学习springboot的路上,现在也算是完成了第一阶段的学习,今天给各位总结总结. 之前在网上找过不少关于springboot的教程,都是一些比 ...

  2. SpringBoot系列七:SpringBoot 整合 MyBatis(配置 druid 数据源、配置 MyBatis、事务控制、druid 监控)

    1.概念:SpringBoot 整合 MyBatis 2.背景 SpringBoot 得到最终效果是一个简化到极致的 WEB 开发,但是只要牵扯到 WEB 开发,就绝对不可能缺少数据层操作,所有的开发 ...

  3. SpringBoot整合Mybatis多数据源 (AOP+注解)

    SpringBoot整合Mybatis多数据源 (AOP+注解) 1.pom.xml文件(开发用的JDK 10) <?xml version="1.0" encoding=& ...

  4. SpringBoot进阶教程 | 第四篇:整合Mybatis实现多数据源

    这篇文章主要介绍,通过Spring Boot整合Mybatis后如何实现在一个工程中实现多数据源.同时可实现读写分离. 准备工作 环境: windows jdk 8 maven 3.0 IDEA 创建 ...

  5. springboot整合mybatis时无法读取xml文件解决方法(必读)

    转    http://baijiahao.baidu.com/s?id=1588136004120071836&wfr=spider&for=pc 在springboot整合myba ...

  6. 三、SpringBoot 整合mybatis 多数据源以及分库分表

    前言 说实话,这章本来不打算讲的,因为配置多数据源的网上有很多类似的教程.但是最近因为项目要用到分库分表,所以让我研究一下看怎么实现.我想着上一篇博客讲了多环境的配置,不同的环境调用不同的数据库,那接 ...

  7. 【springboot spring mybatis】看我怎么将springboot与spring整合mybatis与druid数据源

    目录 概述 1.mybatis 2.druid 壹:spring整合 2.jdbc.properties 3.mybatis-config.xml 二:java代码 1.mapper 2.servic ...

  8. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例

    1.前言 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例. 使用技术:SpringBoot.mybatis.shiro.thymeleaf.pagehelp ...

  9. SpringBoot整合MyBatisPlus配置动态数据源

    目录 SpringBoot整合MyBatisPlus配置动态数据源 SpringBoot整合MyBatisPlus配置动态数据源 推文:2018开源中国最受欢迎的中国软件MyBatis-Plus My ...

随机推荐

  1. 如何打通CMDB,实现就近访问

    CMDB在企业中,一般用于存放与机器设备.应用.服务等相关的元数据.当企业的机器及应用达到一定规模后就需要这样一个系统来存储和管理它们的元数据.有一些广泛使用的属性,例如机器的IP.主机名.机房.应用 ...

  2. sysbench的框架实现介绍

    sysbench是一个非常经典的综合性能测试工具,它支持CPU,IO,内存,尤其是数据库的性能测试.那它是怎么做到通用性的呢,总结一句话是大量运用了重载的方法. sysbench总体架构 sysben ...

  3. REST API设计指导——译自Microsoft REST API Guidelines(四)

    前言 前面我们说了,如果API的设计更规范更合理,在很大程度上能够提高联调的效率,降低沟通成本.那么什么是好的API设计?这里我们不得不提到REST API. 关于REST API的书籍很多,但是完整 ...

  4. Django学习笔记(9)—— 开发用户注册与登录系统

    一,项目题目: 开发用户注册与登录系统 该项目主要练习使用Django开发一个用户注册与登录的系统,通过这个项目然后巩固自己这段时间所学习的Django知识. 二,项目需求: 开发一个简单的用户登录与 ...

  5. 再探go modules:使用与细节

    还有半个月go1.12就要发布了.这是首个将go modules纳入正式支持的稳定版本. 距离go modules随着go1.11正式面向广大开发者进行体验也已经过去了半年,这段时间go module ...

  6. Java开发笔记(一)第一个Java程序

    安装完Java的开发环境Eclipse之后,正是初学者大展身手的时候了,接下来不妨跟着笔者一步一步来,看看第一个Java程序是怎么跑起来的.一开始双击桌面上的Eclipse图标,稍等片刻便弹出Ecli ...

  7. Java开发笔记(六十七)清单:ArrayList和LinkedList

    前面介绍了集合与映射两类容器,它们的共同特点是每个元素都是唯一的,并且采用二叉树方式的类型还自带有序性.然而这两个特点也存在弊端:其一,为啥内部元素必须是唯一的呢?像手机店卖出了两部Mate20,虽然 ...

  8. JavaScript 的 4 种数组遍历方法: for VS forEach() VS for/in VS for/of

    我们有多种方法来遍历 JavaScript 的数组或者对象,而它们之间的区别非常让人疑惑.Airbnb 编码风格禁止使用 for/in 与 for/of,你知道为什么吗? 这篇文章将详细介绍以下 4 ...

  9. 20190328-CSS样式一:字体样式font-、文本样式text-、背景图样式background-

    目录 CSS参考手册:http://css.doyoe.com/ 1.字体简写:font:font-style || font-variant || font-weight || font-size ...

  10. java 应用程序的编译和运行

    1.java 文件的编译和执行步骤. 第一步:使用编辑器编辑  后缀为java的文件,里面包含主类(包含 main()函数), 源文件的命名规则是,如果源文件中有多个类,那么只能有一个类是public ...