SpringBoot Mybatis双数据源的配置

近期因为公司项目的需要,用上了maven和Springboot,对于java开发这块,早闻maven是个好东西,但一直没有去用,感觉用maven帮我们自己做了太多的事情,一个项目跑起来都不知道背后做了些什么,现在想想,可能那个时候脑子进水了吧。

Springboot作为Spring的简约版(我是这么叫的,没有任何依据),将原来Spring需要做的配置文件,改为了注解,提供了大量的***start组件来帮我们做了很多初始化的处理。

但是今天我想要分享的不是maven如何搭建一个helloword的项目,也不是演示Springboot如何入门。这些网上有很多例子,我想我后续也会慢慢整理属于我的一套。今天想分享的是如何用Springboot配置多数据源(dataSource)的问题,之前一直知道Springboot可以很方便的额管理多数据源,当时遇到这个问题的时候,在网上查找了很长时间,也看了看Springboot的官方文档,都没有找到自己想要的解决方案,无奈看了看Spring是如何配置多数据源的,慢慢的有了些思路,废话不说了,开始吧

1.准备:一个maven工程,mysql数据库

2.pom.xml配置

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

3.创建两个数据库company1,company2

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `userid` int(11) NOT NULL,
  `username` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (‘0‘, ‘Hello World‘);

company2中创建表t_subject

-- ----------------------------
-- Table structure for t_subject
-- ----------------------------
DROP TABLE IF EXISTS `t_subject`;
CREATE TABLE `t_subject` (
  `subid` int(11) NOT NULL,
  `subname` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`subid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_subject
-- ----------------------------
INSERT INTO `t_subject` VALUES (‘0‘, ‘Start‘);

4.application.properties增加对数据源的配置

#database1 config
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/company1?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
#database2 config
spring.datasource2.driver-class-name=com.mysql.jdbc.Driver
spring.datasource2.url=jdbc:mysql://127.0.0.1:3306/company2?useUnicode=true&characterEncoding=utf-8
spring.datasource2.username=root
spring.datasource2.password=root

5.配置类的实现

首先是ApplicationStart.java

没有其他的意义,只是让它成为程序的入口

@SpringBootApplication(scanBasePackages="springboot.start",excludeName={"springboot.start.db.company1.mapper","springboot.start.db.company2.mapper"})
public class ApplicationStart {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationStart.class, args);
    }
}

数据源的配置,因为有两个数据源,最好是用两个配置类进行初始话,原因后面会提到

第一个数据源:MysqlDataSource1Config

@Configuration
@MapperScan("springboot.start.db.company1.mapper")
public class MysqlDataSource1Config {
    @Bean(name = "primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource dataSource(){
        return DataSourceBuilder.create().build();
    }
    @Bean(name="primarySqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        return sessionFactory.getObject();
    }
}

第二个数据源:MysqlDataSource2Config

@Configuration
@MapperScan("springboot.start.db.company2.mapper")
public class MysqlDataSource2Config {
    @Bean(name = "secondDataSource")
    @ConfigurationProperties(prefix="spring.datasource2")
    public DataSource dataSource(){
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "secondSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        return sessionFactory.getObject();
    }
}

我的整个包层次如下

下面来看看DbService是怎么用这两个数据源的

@Service
public class DbService {
    @Autowired
    TUserMapper tUserMapper;
    @Autowired
    TSubjectMapper tSubjectMapper;
    /**查询第一个数据源的表
     * 根据uid查询user
     * @param uid
     * @return
     */
    public TUser selectUserById(int uid){
        TUser tUser = null;
        TUserExample example = new TUserExample();
        Criteria criteria = example.createCriteria();
        criteria.andUseridEqualTo(uid);
        List<TUser> users = tUserMapper.selectByExample(example);
        if(users!=null && users.size()>0){
            tUser = users.get(0);
        }
        return tUser;
    }
    /**
     * 查询第二个数据源的表
     * @param sid
     * @return
     */
    public TSubject selectSubjectById(int sid){
        TSubject subject = null;
        TSubjectExample example = new TSubjectExample();
        example.createCriteria().andSubidEqualTo(sid);
        List<TSubject> subjects = tSubjectMapper.selectByExample(example);
        if(subjects!=null && subjects.size()>0){
            subject = subjects.get(0);
        }
        return subject;
    }
}

是不是很简单,不管怎么说,我来看看测试的情况

第二个呢……

靠出错了,尼玛,这是要打脸的节奏,从异常的意思来看是说程序还是从数据源1中去查的t_subject表,为什么呢?

回到第二个数据源的配置,再看看MapperScan的属性,其中有一个sqlSessionFactoryRef,天哪噜,这个Spring中的xml配置何其的相似啊,于是乎在第二个数据源上加上sqlSessionFactoryRef="secondSqlSessionFactory" (secondSqlSessionFactory在bean注解是做了声明的)

至此呢,关于Springboot和mybatis关于双数据源的配置问题,就告一段落了,对于多数据源也适用哦,小菜试过了的

总结:

1.不同数据源的配置,要写在不同的配置类中个,因为MapperScan好像只支持(猜的,有待深入)一个数据源的配置

2.不同数据源对应的mapper,实体类,最好放在不同的包下,在指定MapperScan中的basePackages时,如果两个数据源的包结构出现父子关系,子包的MapperScan好像就不再生效了,如一个数据源的的mapper,实体类放在springboot.datasource包中,第二个数据源的mapper,实体类放在了springboot.datasource.datasource2中,后面那个MapperScan就不会在扫了,这点我没有直接的截图那样的依据,但我有试过不分包的情况,那样只会有一个默认的那个数据源有效(我的理解是,MapperScan应该是有一个处理机制,当遇到basePackages出现包含关系时,将会实现范围大的那个)

3.在多数据源的配置时,注意在默认的那个要加上@primary

4.在非primary配置中,要注意sqlSessionFactoryRef的配置(当然这个只有用mybatis时需要的)

文中涉及的代码可见 https://github.com/yyb0107/springboot.study

时间: 2024-08-24 19:04:44

SpringBoot Mybatis双数据源的配置的相关文章

Spring Boot2.4双数据源的配置

相较于单数据源,双数据源配置有时候在数据分库的时候可能更加有利 但是在参考诸多博客以及书籍(汪云飞的实战书)的时候,发现对于spring boot1.X是完全没问题的,一旦切换到spring boot2.X的时候,就会报出无法实例化出数据源对象等各种问题.我猜测这是无法很好的读取到数据源配置信息的关系. 目前来说,官方文档示例比较好的解决了这个问题 配置双数据源 这里使用java配置方式,需要注意以下几点: 主数据源要加上@Primary注解 需要通过构建DataSourceProperties

spring-boot支持双数据源mysql+mongo

这里,首先想说的是,现在的web应用,处理的数据对象,有结构化的,也有非结构化的.同时存在.但是在spring-boot操作数据库的时候,若是在properties文件中配置数据源的信息,通过默认配置加载数据源的话,往往只会启动一个. 我出于想弄清如何配置数据源的目的,在这里demo一个配置两个数据源的例子.分别是mysql和mongo.mysql的持久化采用的是mybatis. mongo的操作比较简单,直接贴上配置数据库的代码: 1 package com.shihuc.dbconn.sou

基于springboot的多数据源自动配置实现

最近做了一个自动支持多数据源配置的功能,基于springboot生态扩展,可自动识别配置文件中的数据库配置参数,并进行autoconfig. multiple-datasource多数据源支持模块 功能性 支持自动化配置多个数据源: 支持自动化配置持久层框架(mybatis): 支持自动化配置分布式事务管理器(JTA-Atomikos): 支持不同数据源使用不同数据库: 支持不同数据源使用不同数据库且使用不同连接池(hikari.dbcp2.tomcat-pool.druid等): 支持自动适配

【转】Spring, MyBatis 多数据源的配置和管理

同一个项目有时会涉及到多个数据库,也就是多数据源.多数据源又可以分为两种情况: 1)两个或多个数据库没有相关性,各自独立,其实这种可以作为两个项目来开发.比如在游戏开发中一个数据库是平台数据库,其它还有平台下的游戏对应的数据库: 2)两个或多个数据库是master-slave的关系,比如有mysql搭建一个 master-master,其后又带有多个slave:或者采用MHA搭建的master-slave复制: 目前我所知道的 Spring 多数据源的搭建大概有两种方式,可以根据多数据源的情况进

第九章 springboot + mybatis + 多数据源 (AOP实现)

在第八章 springboot + mybatis + 多数据源代码的基础上,做两点修改 1.ShopDao package com.xxx.firstboot.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.xxx.firstboot.domain.Shop; import com.xx

Spring, MyBatis 多数据源的配置和管理

同一个项目有时会涉及到多个数据库,也就是多数据源.多数据源又可以分为两种情况: 1)两个或多个数据库没有相关性,各自独立,其实这种可以作为两个项目来开发.比如在游戏开发中一个数据库是平台数据库,其它还有平台下的游戏对应的数据库: 2)两个或多个数据库是master-slave的关系,比如有mysql搭建一个 master-master,其后又带有多个slave:或者采用MHA搭建的master-slave复制: 目前我所知道的 Spring 多数据源的搭建大概有两种方式,可以根据多数据源的情况进

第八章 springboot + mybatis + 多数据源(转载)

本篇博客转发自:http://www.cnblogs.com/java-zhao/p/5413845.html 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构: 简要原理: 1)DatabaseType列出所有的数据源的key---key 2)DatabaseContextHolder是一个线程安全的DatabaseType容器,并提供了向其中设置和获取DatabaseType的方法 3)DynamicDataSource继承AbstractRoutin

第八章 springboot + mybatis + 多数据源

在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构: 简要原理: 1)DatabaseType列出所有的数据源的key---key 2)DatabaseContextHolder是一个线程安全的DatabaseType容器,并提供了向其中设置和获取DatabaseType的方法 3)DynamicDataSource继承AbstractRoutingDataSource并重写其中的方法determineCurrentLookupKey(),在该方法中使用Da

SpringBoot (七) :springboot + mybatis 多数据源最简解决方案

原文出处: 纯洁的微笑 说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解决方案,还有的是利用aop动态切换,感觉有点小复杂,其实我只是想找一个简单的多数据支持而已,折腾了两个小时整理出来,供大家参考. 配置文件 pom包就不贴了比较简单该依赖的就依赖,主要是数据库这边的配置: mybatis.config-locations=classpath: