dynamic-datasource动态数据源学习

学习链接

spring整合mybatis的核心思路 & 数据源动态切换 & 多数据源事务控制 - 自己的链接(本篇文章的上篇)

Mybatisplus生成代码配置 & p6spy打印sql & mybatis日志打印 & mybatisplus用法

dynamic-datasource-spring-boot-starter 的gitee地址
dynamic-datasource官方文档(收费)(使用自己的qq登录即可)

SpringBoot多数据源

【Java多数据源实现教程】实现动态数据源、多数据源切换方式

springboot多数据源使用
SpringBoot实现多数据源(六)【dynamic-datasource 多数据源组件】
【Java多数据源实现教程】实现动态数据源、多数据源切换方式
Springboot多数据源配置详解
SpringBoot多数据源配置

基础介绍

简介

dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。

其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.x.x。

特性

  • 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
  • 支持数据库敏感配置信息 加密 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的分布式事务方案
  • 提供 本地多数据源事务方案(不能和原生spring事务混用)

约定

  • 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
  • 配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称相同组名称的数据源会放在一个组下
  • 切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换
  • 默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改。
  • 方法上的注解优先于类上注解
  • DS支持继承抽象类上的DS,暂不支持继承接口上的DS

使用方法

1. 引入dynamic-datasource-spring-boot-starter

<dependency>
  <groupId>com.baomidougroupId>
  <artifactId>dynamic-datasource-spring-boot-starterartifactId>
  <version>${version}version>
dependency>

2. 配置数据源

以下会配置一个默认库master,一个组slave(组名)下有两个子库slave_1(组名为slave组下的数据源名称slave_1) 和 slave_2(组名为slave组下的数据源名称slave_2)

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: ENC(xxxxx) # 内置加密,使用请查看详细文档
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: com.mysql.jdbc.Driver
          
       #......省略

其它配置示例

# 多主多从                      纯粹多库(记得设置primary)                   混合配置
spring:                               spring:                               spring:
  datasource:                           datasource:                           datasource:
    dynamic:                              dynamic:                              dynamic:
      datasource:                           datasource:                           datasource:
        master_1:                             mysql:                                master:
        master_2:                             oracle:                               slave_1:
        slave_1:                              sqlserver:                            slave_2:
        slave_2:                              postgresql:                           oracle_1:
        slave_3:                              h2:                                   oracle_2:

3. 使用 @DS 切换数据源

@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解
在这里插入图片描述

@Service
@DS("slave")
public class UserServiceImpl implements UserService {

  @Autowired
  private JdbcTemplate jdbcTemplate;

  public List selectAll() {
    return  jdbcTemplate.queryForList("select * from user");
  }
  
  @Override
  @DS("slave_1")
  public List selectByCondition() {
    return  jdbcTemplate.queryForList("select * from user where age >10");
  }
}

数据源切换示例

简单演示下使用@DS注解,切换指定的数据源

准备数据库

准备2个数据库,一个m_db(作为主库),一个s_db(作为从库),这2个数据库中都有一张account表,表中仅有id和nick_name字段

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nick_name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

pom.xml

导入mybatis-plus(不一定要用mybatis-plus,只是因为懒得自己写mapper.xml文件) 和 dynamic-datasource 的依赖


<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion>

    
	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.1.8.RELEASEversion>
		<relativePath/> 
	parent>

    
	<groupId>com.zzhuagroupId>
	<artifactId>sdynamic-datasource-demoartifactId>
	<version>0.0.1-SNAPSHOTversion>
	<name>springboot-demoname>
	<description>Demo project for Spring Bootdescription>

    
	<properties>
		<java.version>1.8java.version>
	properties>

	<dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        
		<dependency>
			<groupId>mysqlgroupId>
			<artifactId>mysql-connector-javaartifactId>
			<scope>runtimescope>
		dependency>

        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>

        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.5.1version>
        dependency>

        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-generatorartifactId>
            <version>3.5.3version>
        dependency>

        <dependency>
            <groupId>p6spygroupId>
            <artifactId>p6spyartifactId>
            <version>3.9.1version>
        dependency>

        <dependency>
            <groupId>org.freemarkergroupId>
            <artifactId>freemarkerartifactId>
        dependency>

        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>dynamic-datasource-spring-boot-starterartifactId>
            <version>3.5.1version>
        dependency>

        
        <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-swagger2artifactId>
            <version> 2.7.0version>
        dependency>
        
        <dependency>
            <groupId>com.github.xiaoymingroupId>
            <artifactId>swagger-bootstrap-uiartifactId>
            <version>1.9.6version>
        dependency>


        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>


        
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-configuration-processorartifactId>
			<optional>trueoptional>
		dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>

        
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintagegroupId>
					<artifactId>junit-vintage-engineartifactId>
				exclusion>
			exclusions>
		dependency>

        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
        dependency>
	dependencies>

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

project>

application.yml

#spring:
#  datasource:
#    type: com.zaxxer.hikari.HikariDataSource
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://127.0.0.1:3306/m_db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
#    username: root
#    password: root

spring:
  datasource:
    dynamic:
      primary: master
      strict: true
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/m_db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver
          hikari:
            min-idle: 2
            max-pool-size: 5
        # 使用下划线, 下划线前面的是组名,整个为数据源标识(若@DS中使用组名, 则会负载均衡该组名下的所有数据源)
        slave_1:
          url: jdbc:mysql://127.0.0.1:3306/s_db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:mapper/**.xml

SpringbootDemoApplication

开启mybatis的mapper接口扫描

@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class SpringbootDemoApplication {

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

}

AccountController

@RestController
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private IAccountService accountService;

    @RequestMapping("createAccount")
    public Object createAccount(@RequestParam("nickName") String nickName) {
        Account account = new Account();
        account.setNickName(nickName);
        accountService.addAccount(account);
        return "ok";
    }

    @RequestMapping("getAccounts")
    public List<Account> getAccounts() {
        return accountService.findAll();
    }


}

IAccountService

public interface IAccountService extends IService<Account> {

    void addAccount(Account account);

    List<Account> findAll();

}

AccountServiceImpl

@DS("master") // 方法中的@DS注解优先
@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements IAccountService {


    @Override
    public void addAccount(Account account) {
        this.save(account);
    }

    @Override
    @DS("slave") // 填写组名, 会负载均衡
    // @DS("slave_1")
    public List<Account> findAll() {
        return this.list();
    }


}

AccountMapper

public interface AccountMapper extends BaseMapper<Account> {

}

AccountMapper.xml


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzhua.mapper.AccountMapper">

    
    <resultMap id="BaseResultMap" type="com.zzhua.entity.Account">
        <id column="id" property="id" />
        <result column="nick_name" property="nickName" />
    resultMap>

    
    <sql id="Base_Column_List">
        id, nick_name
    sql>

mapper>

测试

访问:http://localhost:8080/account/createAccount?nickName=m1,发现数据插入到了m_db数据库中
访问:http://localhost:8080/account/getAccounts,发现查询的是s_db数据库

你可能感兴趣的:(#,mybatis,学习,mybatis,spring,boot)