关于springboot:Spring-Boot-搭配MyBatis及Druid实现多数据源可自动切换

4次阅读

共计 7883 个字符,预计需要花费 20 分钟才能阅读完成。

原文地址:https://blog.lanweihong.com/p…

Github:spring-boot-mybatis-multiple-data-source

增加相干依赖包

编辑 pom.xml 文件,增加相干依赖:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.8</version>
        <relativePath/>
    </parent>
    
<properties>
        <mysql.driver.version>8.0.16</mysql.driver.version>
        <mybatis.spring.boot.version>1.3.2</mybatis.spring.boot.version>
        <druid.version>1.1.10</druid.version>
        <tk.mybatis.version>2.1.5</tk.mybatis.version>
        <lombok.version>1.16.18</lombok.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.spring.boot.version}</version>
        </dependency>

        <!-- mysql driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.driver.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-autoconfigure</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>${tk.mybatis.version}</version>
        </dependency>

    </dependencies>

配置 application.yml 文件

在配置文件 application.yml 中配置数据源:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: Aa123456.
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      initial-size: 5
      max-active: 50
      max-wait: 60000
      min-idle: 5
      # 配置 book 数据源,可自定义
      book:
        # type: com.alibaba.druid.pool.DruidDataSource
        # driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
        # username: root
        # password: 1
      # 配置 user 数据源
      user:
        url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
        # 重新配置明码,未配置则默认应用以上配置的
        username: root
        password: 1

手动配置数据源

主数据源配置

创立配置类 BookDataSourceConfig,配置类须要对 DataSourceDataSourceTransactionManagerSqlSessionFactorySqlSessionTemplate 四个数据项进行配置。当零碎中存在多个数据源时,必须有一个数据源为主数据源,应用 @Primary 注解润饰。

BookDataSourceConfig 配置类:

@Configuration
// 通过在 `@MapperScan` 注解中配置 `basePackages` 和 `sqlSessionTemplateRef` 来实现主动切换数据源
@MapperScan(basePackages = "com.lanweihong.dao.book",
        sqlSessionFactoryRef = "bookSqlSessionFactory", sqlSessionTemplateRef = "bookSqlSessionTemplate")
public class BookDataSourceConfig {

    public static final String MAPPER_LOCATION = "classpath:mapper/book/*.xml";

    /**
     * 主数据源
     * 阐明:@Primary 如果有多个同类的 Bean,该 Bean 优先思考,多数据源时必须配置一个主数据源,用该注解标记
     * @return
     */
    @Primary
    @Bean("bookDataSource")
    @ConfigurationProperties("spring.datasource.druid.book")
    public DataSource bookDataSource(){return DruidDataSourceBuilder.create().build();}

    @Primary
    @Bean("bookTransactionManager")
    public DataSourceTransactionManager bookTransactionManager() {return new DataSourceTransactionManager(bookDataSource());
    }

    @Primary
    @Bean("bookSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("bookDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
        return sqlSessionFactoryBean.getObject();}

    @Primary
    @Bean("bookSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("bookDataSource") DataSource dataSource) throws Exception {return new SqlSessionTemplate(sqlSessionFactory(dataSource));
    }
}

Mybatis 是通过配置的扫描包和对应的 sqlSessionTemplate 来主动切换数据源,即通过在 @MapperScan 注解中配置 basePackagessqlSessionTemplateRef

@MapperScan(basePackages = "com.lanweihong.dao.book",
        sqlSessionFactoryRef = "bookSqlSessionFactory", sqlSessionTemplateRef = "bookSqlSessionTemplate")

配置第二个数据源

编写配置类 UserDataSourceConfig

@Configuration
@MapperScan(basePackages = "com.lanweihong.dao.user", sqlSessionTemplateRef = "userSqlSessionTemplate")
public class UserDataSourceConfig {

    public static final String MAPPER_LOCATION = "classpath:mapper/user/*.xml";

    /**
     * user 数据源
     * @return
     */
    @Bean("userDataSource")
    @ConfigurationProperties("spring.datasource.druid.user")
    public DataSource userDataSource(){return DruidDataSourceBuilder.create().build();}

    @Bean("userTransactionManager")
    public DataSourceTransactionManager userTransactionManager() {return new DataSourceTransactionManager(userDataSource());
    }

    @Bean("userSqlSessionFactory")
    public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
        return sqlSessionFactoryBean.getObject();}

    @Bean("userSqlSessionTemplate")
    public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userDataSource") DataSource dataSource) throws Exception {return new SqlSessionTemplate(userSqlSessionFactory(dataSource));
    }

}

至此,不同数据源的配置已实现,接下来应用了。

应用

按平时失常写和应用 DAOService,Spring 会依据数据源配置的映射主动切换相应的数据源,不须要在 Service 中指定,间接应用即可。

以下 DAO/Mapper/Service/Controller 代码为示例代码,仅列出局部代码,残缺代码请看:https://github.com/lanweihong…

IBookDao

public interface IBookDao extends BaseMapper<BookDO> {BookDO getByBookName(@Param("bookName") String bookName);
}

BookMapper.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="com.lanweihong.dao.book.IBookDao">

    <resultMap id="BaseResultMap" type="com.lanweihong.entity.BookDO">
        <id column="id" jdbcType="BIGINT" property="id" />
        <result column="version" jdbcType="INTEGER" property="version" />
        <result column="book_name" jdbcType="VARCHAR" property="bookName" />
        <result column="status" jdbcType="TINYINT" property="status" />
        <result column="add_time" jdbcType="TIMESTAMP" property="addTime" />
    </resultMap>

    <sql id="BaseColumnList">
        id, version, book_name, status, add_time
    </sql>

    <select id="getByBookName" resultMap="BaseResultMap">
        SELECT <include refid="BaseColumnList" /> FROM book WHERE book_name = #{bookName}
    </select>
    
</mapper>

Service

@Service("bookService")
public class BookServiceImpl implements IBookService {

    private final IBookDao bookDao;

    @Autowired
    public BookServiceImpl(IBookDao bookDao) {this.bookDao = bookDao;}

    @Override
    public List<BookDO> listAll() {return bookDao.selectAll();
    }

    @Override
    public BookDO getByBookName(String bookName) {return bookDao.getByBookName(bookName);
    }
}

Controller

@RestController
@RequestMapping("/api/v1/")
public class MainController {

    private final IUserService userService;
    private final IBookService bookService;

    @Autowired
    public MainController(IUserService userService, IBookService bookService) {
        this.userService = userService;
        this.bookService = bookService;
    }

    @GetMapping("/books")
    public Map<String, Object> queryBooks(@RequestParam(value = "name", required = false) String bookName) {List<BookDO> books = new ArrayList<>();
        if (StringUtil.isEmpty(bookName)) {books = this.bookService.listAll();
        } else {BookDO book = bookService.getByBookName(bookName);
            books.add(book);
        }
        Map<String, Object> result = new HashMap<>(1);
        result.put("data", books);
        return result;
    }

    @GetMapping("/users")
    public Map<String, Object> queryUsers(@RequestParam(value = "name", required = false) String userName) {List<UserDO> users = new ArrayList<>();
        if (StringUtil.isEmpty(userName)) {users = this.userService.listAll();
        } else {UserDO user = userService.getByUserName(userName);
            users.add(user);
        }

        Map<String, Object> result = new HashMap<>(1);
        result.put("data", users);
        return result;
    }
}

测试

启动利用,在浏览器中拜访 http://127.0.0.1:8015/api/v1/usershttp://127.0.0.1:8015/api/v1/books 测试;

我的项目构造

我的项目构造如下图:

代码已上传至 Github:spring-boot-mybatis-multiple-data-source

参考文档

  1. https://blog.csdn.net/acquain…
正文完
 0