GVKun编程网logo

SpringBoot整合MyBatis多数据源(springboot整合mybatisplus多数据源)

11

本文将分享SpringBoot整合MyBatis多数据源的详细内容,并且还将对springboot整合mybatisplus多数据源进行详尽解释,此外,我们还将为大家带来关于16.从零开始学sprin

本文将分享SpringBoot整合MyBatis多数据源的详细内容,并且还将对springboot整合mybatisplus多数据源进行详尽解释,此外,我们还将为大家带来关于16.从零开始学springboot-整合mybatisPlus-多数据源-代码生成器、Spring Boot 整合mybatis 使用多数据源的实现方法、Spring Boot整合MyBatis多数据源、springboot 配置mybatis多数据源的相关知识,希望对你有所帮助。

本文目录一览:

SpringBoot整合MyBatis多数据源(springboot整合mybatisplus多数据源)

SpringBoot整合MyBatis多数据源(springboot整合mybatisplus多数据源)

SpringBoot整合MyBatis多数据源

一、介绍

在平常的项目中,我们有连接数据库的需求。一般都是一个项目一个数据库,但也有例外需要连接多个数据库的。

那么该如何配置,可以达到多数据源的需求呢。

本次为SpringBootMyBatis的整合,其实掌握了需要配置什么,也很容易进行复刻。

推荐访问:个人博客

二、配置

1)数据库准备

首先,我们先准备三个数据库吧,这边都使用MysqL了,实际可以是不同的数据库

  • test数据库

    create database `test` character set utf8mb4 collate utf8mb4_general_ci;
    
    CREATE TABLE `sys_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(32) NOT NULL COMMENT '用户名',
      `password` varchar(128) NOT NULL COMMENT '密码',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
    
    INSERT INTO `sys_user`(`id`, `username`, `password`) VALUES (1, 'banmoon', '1234');
    INSERT INTO `sys_user`(`id`, `username`, `password`) VALUES (2, 'user', '1234');
    
  • test01数据库

    create database `test01` character set utf8mb4 collate utf8mb4_general_ci;
    
    CREATE TABLE `sys_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(32) NOT NULL COMMENT '用户名',
      `password` varchar(128) NOT NULL COMMENT '密码',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
    
    INSERT INTO `sys_user`(`id`, `username`, `password`) VALUES (1, 'test01', '1234');
    INSERT INTO `sys_user`(`id`, `username`, `password`) VALUES (2, 'test01User', '1234');
    
  • test02数据库

    create database `test02` character set utf8mb4 collate utf8mb4_general_ci;
    
    CREATE TABLE `sys_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(32) NOT NULL COMMENT '用户名',
      `password` varchar(128) NOT NULL COMMENT '密码',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
    
    INSERT INTO `sys_user`(`id`, `username`, `password`) VALUES (1, 'test02', '1234');
    INSERT INTO `sys_user`(`id`, `username`, `password`) VALUES (2, 'test02User', '1234');
    

2)配置

首先,maven依赖包不能忘记

<dependency>
    <groupId>MysqL</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>

然后,我们需要在配置文件上配置上三个数据库的配置信息。

spring:
  datasource:
    driver-class-name: com.MysqL.cj.jdbc.Driver
    url: jdbc:MysqL://localhost:3306/test?serverTimezone=Asia/Shanghai&allowMultiQueries=true
    username: root
    password: 1234

dynamic-datasource:
  test01:
    driver-class-name: com.MysqL.cj.jdbc.Driver
    url: jdbc:MysqL://localhost:3306/test01?serverTimezone=Asia/Shanghai&allowMultiQueries=true
    username: root
    password: 1234
  test02:
    driver-class-name: com.MysqL.cj.jdbc.Driver
    url: jdbc:MysqL://localhost:3306/test02?serverTimezone=Asia/Shanghai&allowMultiQueries=true
    username: root
    password: 1234

怎么配置不重要,清爽就好,重点在于读取。

我们需要读取上面配置文件的信息,配置生成sqlSessionTemplatesqlSessionFactoryPlatformTransactionManager,如此来达到多数据源的功能

test数据库连接的相关配置

package com.banmoon.test.config.datasource;

import org.apache.ibatis.session.sqlSessionFactory;
import org.mybatis.spring.sqlSessionfactorybean;
import org.mybatis.spring.sqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = {"com.banmoon.test.persistent.master.mapper"},
        sqlSessionFactoryRef = "mastersqlSessionFactory")
public class MasterDatasourceConfig {

    /**
     * 寻找配置文件中的数据源配置信息
     * @return
     */
    @Primary
    @Bean("masterDatasourceProperties")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSourceProperties dataSourceProperties(){
        return new DataSourceProperties();
    }

    /**
     * 构建数据源
     * @param properties
     * @return
     */
    @Primary
    @Bean("masterDatasource")
    public DataSource dataSource(@Qualifier("masterDatasourceProperties") DataSourceProperties properties){
        DataSource build = DataSourceBuilder.create()
                .driverClassName(properties.getDriverClassName())
                .url(properties.getUrl())
                .username(properties.getUsername())
                .password(properties.getpassword())
                .build();
        return build;
    }

    /**
     * 构建事务管理器
     * @param dataSource
     * @return
     */
    @Primary
    @Bean(name = "masterTransactionManager")
    public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("masterDatasource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 构建sqlSession工厂
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name = "mastersqlSessionFactory")
    public sqlSessionFactory sqlSessionFactory(@Qualifier("masterDatasource") DataSource dataSource) throws Exception {
        final sqlSessionfactorybean sessionfactorybean = new sqlSessionfactorybean();
        sessionfactorybean.setDataSource(dataSource);
        sessionfactorybean.setTypeHandlersPackage("com.banmoon.test.persistent.master.entity");
        sessionfactorybean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/master/*.xml"));
        return sessionfactorybean.getobject();
    }

    /**
     * 构建sqlSession
     * @param sqlSessionFactory
     * @return
     */
    @Primary
    @Bean(name = "mastersqlSessionTemplate")
    public sqlSessionTemplate sqlSessionTemplate(@Qualifier("mastersqlSessionFactory") sqlSessionFactory sqlSessionFactory) {
        return new sqlSessionTemplate(sqlSessionFactory);
    }

}

test01数据库连接的相关配置

package com.banmoon.test.config.datasource;

import org.apache.ibatis.session.sqlSessionFactory;
import org.mybatis.spring.sqlSessionfactorybean;
import org.mybatis.spring.sqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = {"com.banmoon.test.persistent.test01.mapper"},
        sqlSessionFactoryRef = "test01sqlSessionFactory")
public class Test01DatasourceConfig {

    @Bean("test01DatasourceProperties")
    @ConfigurationProperties(prefix = "dynamic-datasource.test01")
    public DataSourceProperties dataSourceProperties(){
        return new DataSourceProperties();
    }

    @Primary
    @Bean("test01Datasource")
    public DataSource dataSource(@Qualifier("test01DatasourceProperties") DataSourceProperties properties){
        DataSource build = DataSourceBuilder.create()
                .driverClassName(properties.getDriverClassName())
                .url(properties.getUrl())
                .username(properties.getUsername())
                .password(properties.getpassword())
                .build();
        return build;
    }

    @Primary
    @Bean(name = "test01TransactionManager")
    public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("test01Datasource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "test01sqlSessionFactory")
    public sqlSessionFactory sqlSessionFactory(@Qualifier("test01Datasource") DataSource dataSource) throws Exception {
        final sqlSessionfactorybean sessionfactorybean = new sqlSessionfactorybean();
        sessionfactorybean.setDataSource(dataSource);
        sessionfactorybean.setTypeHandlersPackage("com.banmoon.test.persistent.test01.entity");
        sessionfactorybean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/test01/*.xml"));
        return sessionfactorybean.getobject();
    }

    @Primary
    @Bean(name = "test01sqlSessionTemplate")
    public sqlSessionTemplate sqlSessionTemplate(@Qualifier("test01sqlSessionFactory") sqlSessionFactory sqlSessionFactory) {
        return new sqlSessionTemplate(sqlSessionFactory);
    }

}

test02数据库连接的相关配置

package com.banmoon.test.config.datasource;

import org.apache.ibatis.session.sqlSessionFactory;
import org.mybatis.spring.sqlSessionfactorybean;
import org.mybatis.spring.sqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = {"com.banmoon.test.persistent.test02.mapper"},
        sqlSessionFactoryRef = "test02sqlSessionFactory")
public class Test02DatasourceConfig {

    @Bean("test02DatasourceProperties")
    @ConfigurationProperties(prefix = "dynamic-datasource.test02")
    public DataSourceProperties dataSourceProperties(){
        return new DataSourceProperties();
    }

    @Primary
    @Bean("test02Datasource")
    public DataSource dataSource(@Qualifier("test02DatasourceProperties") DataSourceProperties properties){
        DataSource build = DataSourceBuilder.create()
                .driverClassName(properties.getDriverClassName())
                .url(properties.getUrl())
                .username(properties.getUsername())
                .password(properties.getpassword())
                .build();
        return build;
    }

    @Primary
    @Bean(name = "test02TransactionManager")
    public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("test02Datasource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "test02sqlSessionFactory")
    public sqlSessionFactory sqlSessionFactory(@Qualifier("test02Datasource") DataSource dataSource) throws Exception {
        final sqlSessionfactorybean sessionfactorybean = new sqlSessionfactorybean();
        sessionfactorybean.setDataSource(dataSource);
        sessionfactorybean.setTypeHandlersPackage("com.banmoon.test.persistent.test02.entity");
        sessionfactorybean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/test02/*.xml"));
        return sessionfactorybean.getobject();
    }

    @Primary
    @Bean(name = "test02sqlSessionTemplate")
    public sqlSessionTemplate sqlSessionTemplate(@Qualifier("test02sqlSessionFactory") sqlSessionFactory sqlSessionFactory) {
        return new sqlSessionTemplate(sqlSessionFactory);
    }

}

还有一个需要注意,我们需要排除掉MybatisAutoConfiguration类,避免它自动进行配置

package com.banmoon.test;

import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(exclude = MybatisAutoConfiguration.class)
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

}

配置完成,那么该如何去写EntityMapper呢?

请注意,在我们构建sqlSessionFactory的时候,就已经指定了它Entity的包路径和Mapper的包路径。

所以我只需要在指定的包路径在创建EntityMapper就可以了。

3)编写实体和Mapper

如下进行编写User.javaUserMapper.javaUserMapper.xml

package com.banmoon.test.persistent.master.entity;

import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

}
package com.banmoon.test.persistent.master.mapper;

import com.banmoon.test.persistent.master.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserMapper {

    List<User> selectList();

}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.banmoon.test.persistent.master.mapper.UserMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.banmoon.test.persistent.master.entity.User">
        <id column="id" property="id" />
        <result column="username" property="username" />
        <result column="password" property="password" />
    </resultMap>
    
    <select id="selectList" resultType="com.banmoon.test.persistent.master.entity.User">
        select * from sys_user
    </select>

</mapper>

由于演示的三个数据库,里面建的表结构都是一样的,这里就不再贴代码了,贴一个包路径结构

image-20220606214416229

image-20220606214444285

4)测试

以前我还很喜欢写Controller去进行测试,现在直接单元测试,直接进行调试了,简单快捷

package com.banmoon.test;

import com.banmoon.test.persistent.master.entity.User;
import com.banmoon.test.persistent.master.mapper.UserMapper;
import com.banmoon.test.persistent.test01.entity.Test01User;
import com.banmoon.test.persistent.test01.mapper.Test01UserMapper;
import com.banmoon.test.persistent.test02.entity.Test02User;
import com.banmoon.test.persistent.test02.mapper.Test02UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBoottest;

import java.util.List;

@SpringBoottest
class ServiceTest {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private Test01UserMapper test01UserMapper;

    @Autowired
    private Test02UserMapper test02UserMapper;

    @Test
    void inserttest() {
        List<User> list = userMapper.selectList();
        list.forEach(System.out::println);

        System.out.println("============");
        List<Test01User> test01UserList = test01UserMapper.selectList();
        test01UserList.forEach(System.out::println);

        System.out.println("============");
        List<Test02User> test02UserList = test02UserMapper.selectList();
        test02UserList.forEach(System.out::println);
    }

}

image-20220606220338657

三、MyBatis-Plus多数据源

1)自己配置

首先就是先写入maven依赖,这一点去官网可以查看到

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>

至于多数据源的配置,其实和上面差不多的,主要需要将sqlSessionFactory改成MyBatis-plus中的实现就可以了,如下

package com.banmoon.test.config.datasource;

import com.baomidou.mybatisplus.extension.spring.MybatissqlSessionfactorybean;
import org.apache.ibatis.session.sqlSessionFactory;
import org.mybatis.spring.sqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = {"com.banmoon.test.persistent.master.mapper"},
        sqlSessionFactoryRef = "mastersqlSessionFactory")
public class MasterDatasourceConfig {

    /**
     * 寻找配置文件中的数据源配置信息
     * @return
     */
    @Primary
    @Bean("masterDatasourceProperties")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSourceProperties dataSourceProperties(){
        return new DataSourceProperties();
    }

    /**
     * 构建数据源
     * @param properties
     * @return
     */
    @Primary
    @Bean("masterDatasource")
    public DataSource dataSource(@Qualifier("masterDatasourceProperties") DataSourceProperties properties){
        DataSource build = DataSourceBuilder.create()
                .driverClassName(properties.getDriverClassName())
                .url(properties.getUrl())
                .username(properties.getUsername())
                .password(properties.getpassword())
                .build();
        return build;
    }

    /**
     * 构建事务管理器
     * @param dataSource
     * @return
     */
    @Primary
    @Bean(name = "masterTransactionManager")
    public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("masterDatasource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 构建sqlSession工厂
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name = "mastersqlSessionFactory")
    public sqlSessionFactory sqlSessionFactory(@Qualifier("masterDatasource") DataSource dataSource) throws Exception {
        // 修改为mp的sqlSessionfactorybean
        final MybatissqlSessionfactorybean sessionfactorybean = new MybatissqlSessionfactorybean();
        sessionfactorybean.setDataSource(dataSource);
        sessionfactorybean.setTypeHandlersPackage("com.banmoon.test.persistent.master.entity");
        sessionfactorybean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/master/*.xml"));
        return sessionfactorybean.getobject();
    }

    /**
     * 构建sqlSession
     * @param sqlSessionFactory
     * @return
     */
    @Primary
    @Bean(name = "mastersqlSessionTemplate")
    public sqlSessionTemplate sqlSessionTemplate(@Qualifier("mastersqlSessionFactory") sqlSessionFactory sqlSessionFactory) {
        return new sqlSessionTemplate(sqlSessionFactory);
    }

}

注意一下,由于只需要引入MyBatis-plus,所以启动类上的排除的类,已经可以不需要了

package com.banmoon.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

}

其他都差不多,是由代码生成器生成的EntityMapper,这里就不贴了,直接翻官网文档吧,里面很详细

上代码测试一下吧,其实和之前差不多,只是使用到的是MyBatis-plus中的方法

package com.banmoon.test;

import com.banmoon.test.persistent.master.entity.User;
import com.banmoon.test.persistent.master.mapper.UserMapper;
import com.banmoon.test.persistent.test01.entity.Test01User;
import com.banmoon.test.persistent.test01.mapper.Test01UserMapper;
import com.banmoon.test.persistent.test02.entity.Test02User;
import com.banmoon.test.persistent.test02.mapper.Test02UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBoottest;

import java.util.List;

@SpringBoottest
class ServiceTest {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private Test01UserMapper test01UserMapper;

    @Autowired
    private Test02UserMapper test02UserMapper;

    @Test
    void inserttest() {
        List<User> list = userMapper.selectList(null);
        list.forEach(System.out::println);

        System.out.println("============");
        List<Test01User> test01UserList = test01UserMapper.selectList(null);
        test01UserList.forEach(System.out::println);

        System.out.println("============");
        List<Test02User> test02UserList = test02UserMapper.selectList(null);
        test02UserList.forEach(System.out::println);
    }

}

image-20220607095738103

2)官方插件

在MyBatis-Plus中,有一个多数据源启动器,它可以做到以下这些功能

  • 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
  • 支持数据库敏感配置信息 加密 ENC()。
  • 支持每个数据库独立初始化表结构schema和数据库database。
  • 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
  • 支持 自定义注解 ,需继承DS(3.2.0+)。
  • 提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。
  • 提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。
  • 提供 自定义数据源来源 方案(如全从数据库加载)。
  • 提供项目启动后 动态增加移除数据源 方案。
  • 提供Mybatis环境下的 纯读写分离 方案。
  • 提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定义。
  • 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
  • 提供 **基于seata的分布式事务方案。
  • 提供 本地多数据源事务方案。

具体还是看官网文档吧,已经写的十分详细了,建议使用!!!

四、最后

虽然最近暂时没有此类的需求,但提前先记录测试一波,免得到时候手忙脚乱。

哦对,现在的确很少使用原生的MyBatis了,最近都是在使用MyBatis-plus

这是一个好框架,十分好用,建议学习,直接使用。

我是半月,祝你幸福!!!

16.从零开始学springboot-整合mybatisPlus-多数据源-代码生成器

16.从零开始学springboot-整合mybatisPlus-多数据源-代码生成器

前言

前几个案例一直只有一个固定的数据源,但是实际开发中我们常常会有多个数据库(分库分表存放业务场景&主从场景),所以本次来做个这样的尝试。 另外,我们此次使用mybatis-plus插件来更方便的进行数据操作。

几个概念

多模块(maven聚合): 我们之前的demo都是一个项目一个文件,但是实际生产场景中,这种方式还是比较少见的,正常一个项目都或或多或少的关联另一个项目,比如开发了一套api项目,这套api肯定会有对应的web项目,app项目等等,那么如何在创建项目时就能体现这种依赖关系呢?maven聚合应运而生。你可以简单的理解为有这么一个父项目,能管理所以依赖它的子项目,当父项目改动编译时,对应的所有子项目都会编译重新打包

mybatis-plus: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis -plus则是在MyBatis 上的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

多数据源: 简而言之,同时连接多个数据库

项目构建

博主使用的是IDEA开发,所以建议大家都使用IDEA。

创建父项目

1.png

2.png

删除src目录,因为父项目不写代码

创建子项目

右键选择父项目 3.png

4.png

5.png

6.png

至此基本的项目结构已经建立,但是实际上demo和web-api的"父子关系"还没有建立,我们需要简单的修改下pom.xml SpringBootDemo/pom.xml:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
    </parent>
    <packaging>pom</packaging>
    <modules>
        <module>sbmp-multidb</module>
    </modules>

7.png

sbmp-multidb/pom.xml更改parent:

    <parent>
        <groupId>com.mrcoder</groupId>
        <artifactId>SpringBootDemo</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

8.png

Tips

那么问题来了,既然所谓的依赖是加载包,那么若我们在父pom.xml中加入一个依赖包,那么子模块会自动继承这个依赖么? 这就引出了maven 关于pom依赖管理的知识。请查看 http://wrsee.com/articles/80

添加依赖

以上完成了多模块的配置,下面我们添加子模块pom.xml依赖

完整依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>


    <parent>
        <groupId>com.mrcoder</groupId>
        <artifactId>SpringBootDemo</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>


    <groupId>com.mrcoder</groupId>
    <artifactId>sbmp-multidb</artifactId>
    <version>0.0.1</version>
    <name>sbmp-multidb</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <spring.boot.version>2.1.0.RELEASE</spring.boot.version>
        <mysql.version>8.0.12</mysql.version>
        <mybatisplus.version>3.0.7.1</mybatisplus.version>
        <dynamic-datasource.version>2.5.0</dynamic-datasource.version>
        <lombok.version>1.18.2</lombok.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!-- lombok简化类 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>${lombok.version}</version>
        </dependency>
        <!-- 多数据源 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>${dynamic-datasource.version}</version>
        </dependency>
        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatisplus.version}</version>
        </dependency>
        <!-- mybatis-plus代码生成器 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatisplus.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>${mybatisplus.version}</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

9.png

10.png

添加配置

application.yml:

spring:
  datasource:
    dynamic:
      primary: db1   #设置默认的数据源
      datasource:
        db1:
          username: root
          password: 123456
          url: jdbc:mysql://192.168.145.131:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
          driver-class-name: com.mysql.cj.jdbc.Driver
        db2:
          username: root
          password: 123456
          url: jdbc:mysql://192.168.145.131:3306/test2?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
          driver-class-name: com.mysql.cj.jdbc.Driver
      mp-enabled: true
logging:
  level:
    com.xkcoding.multi.datasource.mybatis: debug

建库

建立test、test2数据库 test库建表:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for multi_user
-- ----------------------------
DROP TABLE IF EXISTS `multi_user`;
CREATE TABLE `multi_user` (
  `id` bigint(64) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `age` int(30) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of multi_user
-- ----------------------------
INSERT INTO `multi_user` VALUES (''1'', ''主库添加222'', ''20'');

test2库建表:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for multi_user
-- ----------------------------
DROP TABLE IF EXISTS `multi_user`;
CREATE TABLE `multi_user` (
  `id` bigint(64) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `age` int(30) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of multi_user
-- ----------------------------
INSERT INTO `multi_user` VALUES (''1103566261448732674'', ''主库添加'', ''20'');
INSERT INTO `multi_user` VALUES (''1103566303475658753'', ''主库添加'', ''20'');
INSERT INTO `multi_user` VALUES (''1103566435235524610'', ''主库添加'', ''20'');

mybatis-plus代码生成器的使用

以上我们成功创建了一个多模块的项目,父项目为SpringBootDemo,子项目为sbmp-multidb 接下来,我们完善各"层"代码,考虑到手动一个个创建类文件和包太麻烦,这边我们使用一个偷懒工具,mybatis-plus-generator来自动生成相关的包和类文件(和mubatis-generator类似的功能)。

我们先右键新增一个名叫generator的package,里面新增一个MysqlGenerator的类文件, 11.png

12.png

generator/MysqlGenerator:

package com.mrcoder.sbmpmultidb.generator;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * <p>
 * mysql 代码生成器演示例子
 * </p>
 */
public class MysqlGenerator {

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    /**
     * RUN THIS
     */
    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/sbmp-multidb/src/main/java");
        gc.setAuthor("mrcoder");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://192.168.145.131:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(scanner("模块名"));
        pc.setParent("com.mrcoder");
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + "/sbmp-multidb/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        mpg.setTemplate(new TemplateConfig().setXml(null));

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("com.mrcoder.sbmpmultidb.BaseEntity");
        strategy.setEntityLombokModel(true);
        //strategy.setSuperControllerClass("com.mrcoder.sbmpmultidb.BaseController");
        strategy.setInclude(scanner("表名"));
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        // 选择 freemarker 引擎需要指定如下加,注意 pom 依赖必须有!
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

相关的注释已经加上了,自行阅读,或者直接去看官方文档~,根据实际情况酌情修改。

这边我们直接运行代码生成器,点击绿色的小箭头 13.png

运行时会让你填写模块名和数据表名, 14.png

模块名写子模块的名称即可,这边不写子模块名填写其它名字的话则会自动创建一个子模块并将文件生成进去。 数据表名如实填写即可

目录结构

15.png

如图,标红部分为代码生成器自动生成的代码,只需小小的完善即可使用。

controller和service/impl还是需要手动创建的。

完善

我们创建controller和service/impl的package,补充代码

controller/MultiUserController:

package com.mrcoder.sbmpmultidb.controller;


import com.mrcoder.sbmpmultidb.entity.MultiUser;
import com.mrcoder.sbmpmultidb.service.IMultiUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author mrcoder
 * @since 2019-03-07
 */
@Controller
@RestController
@RequestMapping("/sbmpmultidb/multi-user")
public class MultiUserController {
    @Autowired
    private IMultiUserService userService;

    @RequestMapping("/id")
    public MultiUser id(){
        MultiUser user = userService.getById(1);
        return user;
    }

    @RequestMapping("/list")
    public List<MultiUser> list() {
        List<MultiUser> userList = userService.list();
        return userList;
    }

    @RequestMapping("add")
    public String add(){
        MultiUser userMaster = MultiUser.builder().name("主库添加").age(20).build();
        userService.addUser(userMaster);
        return "add success";
    }

    @RequestMapping("update")
    public String update(){

        MultiUser userMaster = MultiUser.builder().id(1L).name("主库添加222").age(20).build();
        userService.updateById(userMaster);
        return "update success";
    }
}

entity/MultiUser:

package com.mrcoder.sbmpmultidb.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author mrcoder
 * @since 2019-02-26
 */
@Data
@TableName("multi_user")
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MultiUser implements Serializable {
    private static final long serialVersionUID = -1923859222295750467L;
    //private static final long serialVersionUID = 1L;

    @TableId(type = IdType.ID_WORKER)
    private Long id;

    private String name;

    private Integer age;

}

mapper/MultiUserMapper:

package com.mrcoder.sbmpmultidb.mapper;

import com.mrcoder.sbmpmultidb.entity.MultiUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author mrcoder
 * @since 2019-03-07
 */
public interface MultiUserMapper extends BaseMapper<MultiUser> {

}

service/IMultiUserService:

package com.mrcoder.sbmpmultidb.service;

import com.mrcoder.sbmpmultidb.entity.MultiUser;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author mrcoder
 * @since 2019-03-07
 */
public interface IMultiUserService extends IService<MultiUser> {
    void addUser(MultiUser user);
}

service/impl/MultiUserServiceImpl:

package com.mrcoder.sbmpmultidb.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.mrcoder.sbmpmultidb.entity.MultiUser;
import com.mrcoder.sbmpmultidb.mapper.MultiUserMapper;
import com.mrcoder.sbmpmultidb.service.IMultiUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author mrcoder
 * @since 2019-03-07
 */
@Service
@DS("db1")
public class MultiUserServiceImpl extends ServiceImpl<MultiUserMapper, MultiUser> implements IMultiUserService {
    @DS("db2")
    @Override
    public void addUser(MultiUser user) {
        baseMapper.insert(user);
    }
}

最后我们在入口文件中加入扫描操作:

SbmpMultidbApplication:

package com.mrcoder.sbmpmultidb;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.mrcoder.sbmpmultidb.mapper")
public class SbmpMultidbApplication {

    public static void main(String[] args) {
        SpringApplication.run(SbmpMultidbApplication.class, args);
    }

}

运行

16.png

项目地址

https://github.com/MrCoderStack/SpringBootDemo/tree/master/sbmp-multidb

https://gitee.com/MrCoderStack/SpringBootDemo/tree/master/sbmp-multidb

请关注我的订阅号

订阅号.png

Spring Boot 整合mybatis 使用多数据源的实现方法

Spring Boot 整合mybatis 使用多数据源的实现方法

前言

本篇教程偏向实战,程序猿直接copy代码加入到自己的项目中做简单的修修改改便可使用,而对于springboot以及mybatis不在此进行展开介绍,如有读者希望了解可以给我留言,并持续关注,我后续会慢慢更新。(黑色区域代码部分,安卓手机可手动向左滑动,来查看全部代码)

整合

其实整合很简单,如果是用gradle的话,在build.gradle文件里加入

compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1')

如果是用maven的话在pom.xml文件里加入

 

单库配置:

引入之后,默认情况下,Spring Boot会自动为我们配置好一个DataSource,它会在classpath中搜索H2、hsqldb等内存数据库的jar包,如果找到了,就会自动配置一个内存数据库的DataSource。

如果在application.yml或application.property中指定了spring.datasource.*的相关配置参数,Spring Boot就会使用该配置创建一个DataSource。

然后会自动创建使用该DataSource的sqlSessionfactorybean以及sqlSessionTemplate。会自动扫描你的Mappers,连接到sqlSessionTemplate,并注册到Spring上下文中。

 spring.datasource.url=jdbc:MysqL://localhost/test
 spring.datasource.username=dbuser
 spring.datasource.password=dbpass
 spring.datasource.driver-class-name=com.MysqL.jdbc.Driver

更多参数请查看DataSourceProperties

多库配置:

由于业务需要,项目要同时使用多个数据库进行业务开发:

首先,我们必须在application.property中自定义两个数据源的配置,一个使用first.datasource.*,另一个使用second.datasource.*,为了能使别人一眼看出连接的是什么库,可以使用数据库命名,比如user库,则可以使用user.datasource.*,在使用多数据源的时候,所有必要配置都不能省略。

first.datasource.url=jdbc:MysqL://localhost/first
first.datasource.username=dbuser1
first.datasource.password=dbpass1
first.datasource.driver-class-name=com.MysqL.jdbc.Driver
first.datasource.type=com.alibaba.druid.pool.DruidDataSource//我用的是Druid,也可以不加用默认的
second.datasource.url=jdbc:MysqL://localhost/second
second.datasource.username=dbuser2
second.datasource.password=dbpass2
second.datasource.driver-class-name=com.MysqL.jdbc.Driver
second.datasource.type=com.alibaba.druid.pool.DruidDataSource

直接上代码,我的做法是将两个数据源用两个配置类创建:

@Configuration
@MapperScan(basePackages = {"com.user.server.dao"},sqlSessionTemplateRef = "usersqlSessionTemplate")
public class UserMybatisConfig {
 @Bean(name = "userDataSource")
 @Primary //必须加此注解,不然报错,下一个类则不需要添加
 @ConfigurationProperties(prefix = "first.datasource") // prefix值必须是application.properteis中对应属性的前缀
 public DataSource userDataSource() {
  return DataSourceBuilder.create().build();
 }
 @Bean
 public sqlSessionFactory usersqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {
  sqlSessionfactorybean bean = new sqlSessionfactorybean();
  bean.setDataSource(dataSource);
  //添加XML目录
  ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
 try {
   bean.setMapperLocations(resolver.getResources("classpath*:com/user/server/dao/mapping/*.xml"));
   return bean.getobject();
  } catch (Exception e) {
   e.printstacktrace();
   throw new RuntimeException(e);
  }
 }
 @Bean
 public sqlSessionTemplate usersqlSessionTemplate(@Qualifier("usersqlSessionFactory") sqlSessionFactory sqlSessionFactory) throws Exception {
  sqlSessionTemplate template = new sqlSessionTemplate(sqlSessionFactory); // 使用上面配置的Factory
  return template;
 }
}
@Configuration
@MapperScan(basePackages = {"com.airmi.server.dao"},sqlSessionTemplateRef = "autoTestsqlSessionTemplate")
 public class AutoTestMybatisConfig {
  @Bean
  @ConfigurationProperties(prefix = "autotest.datasource")
   public DataSource autoTestDataSource() {
   return DataSourceBuilder.create().build();
  }
  @Bean
  public sqlSessionTemplate autoTestsqlSessionTemplate(@Qualifier("autoTestsqlSessionFactory") sqlSessionFactory sqlSessionFactory) throws Exception {
   sqlSessionTemplate template = new sqlSessionTemplate(sqlSessionFactory);
    return template;
   }
  @Bean
  public sqlSessionFactory autoTestsqlSessionFactory(@Qualifier("autoTestDataSource") DataSource dataSource) throws Exception {
   sqlSessionfactorybean bean = new sqlSessionfactorybean();
   bean.setDataSource(dataSource);
   //添加XML目录
   ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
   try {
    bean.setMapperLocations(resolver.getResources("classpath*:com/airmi/server/dao/mapping/*.xml"));
    return bean.getobject();
   } catch (Exception e) {
    e.printstacktrace();
    throw new RuntimeException(e);
   }
  }
 }

 @Primary //该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让autowire注解报错,官网要求当多个数据源时,必须指定一个datasource,另一个datasource则不用添加。

@Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)。

 @MapperScan (basePackages = {"com.user.server.dao"},sqlSessionTemplateRef = "usersqlSessionTemplate") basePackages为mapper所在的包,sqlSessionTemplateRef要引用的实例。

user代码结构如下:

 

总结

以上所述是小编给大家介绍的Spring Boot 整合mybatis 使用多数据源的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

您可能感兴趣的文章:

  • 详解SpringBoot和Mybatis配置多数据源
  • 详解Spring Boot整合Mybatis实现 Druid多数据源配置
  • Spring Boot 集成Mybatis实现主从(多数据源)分离方案示例
  • springboot + mybatis配置多数据源示例
  • Spring+MyBatis多数据源配置实现示例
  • Spring与Mybatis相结合实现多数据源切换功能

Spring Boot整合MyBatis多数据源

Spring Boot整合MyBatis多数据源

Spring Boot整合MyBatis多数据源

  对于Spring Boot 整合JdbcTemplate多数据源,此方式相对比较复杂一些,没有整合JdbcTemplate多数据源相对简单一些,但此方式也是一种技术,我们也是要掌握的。

创建工程

首先我们需要创建一个Spring Boot 项目工程,并且添加Mybatis、Mysql以及web的相关依赖:

在这里插入图片描述

创建好项目后,由于我们每个人的数据库版本不一样,我们要自己指定版本号,这里,我的数据库版本使用的依赖时5.1.47版本的,并且添加数据库连接池Druid依赖,我们整合JdbcTemplate时也是要添加Druid依赖,但是我们要添加Spring Boot打造的Druid,不能使用传统的Druid。依赖如下:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

多数据源配置

首先,我们要有两个数据源,数据库中有两个数据源。然后,我们在项目中application.properties中配置数据库基本信息,然后提供两个DataSource即可。application.properties中的配置如下:

spring.datasource.one.url=jdbc:mysql:///zmf
spring.datasource.one.username=root
spring.datasource.one.password=root
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.driver-class-name=com.mysql.jdbc.Driver


spring.datasource.two.url=jdbc:mysql:///test
spring.datasource.two.username=root
spring.datasource.two.password=root
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.driver-class-name=com.mysql.jdbc.Driver

然后,我们再提供两个DataSource,如下:

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.one")
    DataSource dsOne() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.two")
    DataSource dsTwo() {
        return DruidDataSourceBuilder.create().build();
    }
}

Mybatis的配置

对于Mybatis的配置,相对于JdbcTemplate的配置是有那么麻烦一点,因为要提供SqlSessionFactory和SqlSessionTemplate这两个bean,所以这里的两个数据源我们将在两个类中分开来配置。下面我们先看第一个数据源Mybatis的配置:

@Configuration
@MapperScan(basePackages = "org.zmf.mybatis.mapper1",sqlSessionFactoryRef = "sqlSessionFactoryOne",sqlSessionTemplateRef = "sqlSessionTemplateOne")
public class MybatisConfigOne {

    @Resource(name = "dsOne")
    DataSource dsOne;

    @Bean
    SqlSessionFactory sqlSessionFactoryOne() {
        SqlSessionFactory sessionFactory = null;
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dsOne);
        try {
            sessionFactory = bean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }

    @Bean
    SqlSessionTemplate sqlSessionTemplateOne() {
        return new SqlSessionTemplate(sqlSessionFactoryOne());
    }
}

说明:创建MyBatisConfigOne类,首先指明该类是一个配置类,配置类中要扫描的包是org.zmf.mybatis.mapper1,即该包下的Mapper接口将操作dsOne中的数据,对应的SqlSessionFactory和SqlSessionTemplate分别是sqlSessionFactoryOne和sqlSessionTemplateOne,在MyBatisConfigOne内部,分别提供SqlSessionFactory和SqlSessionTemplate即可,SqlSessionFactory根据dsOne创建,然后再根据创建好的SqlSessionFactory创建一个SqlSessionTemplate。

下面,我们配置第二个数据源:

@Configuration
@MapperScan(basePackages = "org.zmf.mybatis.mapper2",sqlSessionFactoryRef = "sqlSessionFactoryTwo",sqlSessionTemplateRef = "sqlSessionTemplateTwo")
public class MybatisConfigTwo {

    @Resource(name = "dsTwo")
    DataSource dsTwo;

    @Bean
    SqlSessionFactory sqlSessionFactoryTwo() {
        SqlSessionFactory sessionFactory = null;
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dsTwo);
        try {
            sessionFactory = bean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }

    @Bean
    SqlSessionTemplate sqlSessionTemplateTwo() {
        return new SqlSessionTemplate(sqlSessionFactoryTwo());
    }
}

bean创建

根据以上配置,我们先创建mapper所需要的bean,因为我的两个数据源中的数据不一致所以创建如下:

public class User {
    private Integer id;
    
    private String name;
    
    private String password;
    
	//此处省略get和set方法
}
public class Book {
    private Integer id;
    
    private String name;
    
    private String author;

	//此处省略get和set方法
}

mapper创建

根据上面的配置,下面我们创建所需要的mapper: 首先我们先创建org.zmf.mybatis.mapper1中的mapper:

public interface UserMapper {

    List<User> getAllUser();
}

对应的XML文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zmf.mybatis.mapper1.UserMapper">
    <select id="getAllUser" resultType="org.zmf.mybatis.bean.User">
        select * from user
    </select>
</mapper>

org.zmf.mybatis.mapper2中的mapper:

public interface BookMapper {
    List<Book> getAllBook();
}

对应的XML文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zmf.mybatis.mapper2.BookMapper">
    <select id="getAllBook" resultType="org.zmf.mybatis.bean.Book">
        select * from book
    </select>
</mapper>

测试

测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MybatisApplicationTests {

    @Autowired
    UserMapper userMapper;

    @Autowired
    BookMapper bookMapper;
    @Test
    public void contextLoads() {
        List<User> allUser = userMapper.getAllUser();
        System.out.println(allUser);

        List<Book> allBook = bookMapper.getAllBook();
        System.out.println(allBook);
    }

}

注意:到这里我们启动可能会报错:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): org.zmf.mybatis.mapper1.UserMapper.getAllUser

原因,我们在启动的时候,Spring Boot默认把我们mapper1和mapper2中的xml文件过滤掉了。 解决办法: 我们在pom文件中build节点中添加如下配置:

<resources>
   <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*xml</include>
        </includes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
    </resource>
</resources>

再次启动一样报同样的错误,那就把项目中的target删掉,重新启动:

在这里插入图片描述

springboot 配置mybatis多数据源

springboot 配置mybatis多数据源

配置mybatis的包和驱动不再多说,进入操作步骤

1.配置yml或者properties文件,填写多数据源地址及连接账户

2.编写configuration,不再让spring自动配置数据源,自定义实现

2.1

@Configuration
public class DataSourceConfig {

    @Bean(name = "www4mmbprice")
    @ConfigurationProperties(prefix = "spring.datasource.druid.data1") // application.properteis中对应属性的前缀
    public DataSource mmbPrice() {
        return DataSourceBuilder.create().build();
    }


    @Primary
    @Bean(name = "data3mmbPirceData")
    @ConfigurationProperties(prefix = "spring.datasource.druid.data2") // application.properteis中对应属性的前缀
    public DataSource mmbPriceData()
    {
        return DataSourceBuilder.create().build();
    }
}

2.2

sqlSessionFactoryRef = "www4SqlSessionFactory",

sqlSessionTemplateRef = "www4SqlSessionTemplate"这些都要跟自己编写的bean对应

Qualifier是根据名字去找Bean方法

 

package com.manmanbuy.rrmq.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
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.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;


@Configuration
@MapperScan(basePackages = "需要扫描的mapper包,到路径位置,不要点到具体的类", sqlSessionFactoryRef = "www4SqlSessionFactory",sqlSessionTemplateRef = "www4SqlSessionTemplate" )
public class DataSourceMmbPrice {


    @Autowired
    @Qualifier("www4mmbprice")
    private DataSource mmbPriceDataSource;

    @Bean(name = "www4SqlSessionFactory")
    public SqlSessionFactory mmbPriceSqlSessionFactory() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(mmbPriceDataSource);
        //bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/**/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "www4TransactionManager")
    public DataSourceTransactionManager mmbPriceTransactionManager() {
        return new DataSourceTransactionManager(mmbPriceDataSource);
    }

    @Bean(name = "www4SqlSessionTemplate")
    public SqlSessionTemplate www4mmbPriceSqlSessionTemplate(@Qualifier("www4SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {

        SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory);

        return template;
    }
}

3.编写mapper接口

3.1 如果mybatis使用注解形式写sql到这里就结束了

3.2 如果使用xml配置,需要在上述步骤中的sessionFactory中配置XML路径

bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/mmbpricedata/*.xml"));

注意:这里只有一点要注意,mapper接口文件必须放在不同的包下,不然会找不到对应的mapper接口。尝试过很多方法,都不行,只能分开!!!

 

4.在其他类文件中直接autowire注入接口即可

 

 

今天关于SpringBoot整合MyBatis多数据源springboot整合mybatisplus多数据源的介绍到此结束,谢谢您的阅读,有关16.从零开始学springboot-整合mybatisPlus-多数据源-代码生成器、Spring Boot 整合mybatis 使用多数据源的实现方法、Spring Boot整合MyBatis多数据源、springboot 配置mybatis多数据源等更多相关知识的信息可以在本站进行查询。

本文标签: