最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot + Mybatis 實現(xiàn)動態(tài)數(shù)據(jù)源案例分析

 更新時間:2018年11月02日 08:32:37   作者:朝雨憶輕塵  
這篇文章主要介紹了Spring Boot + Mybatis 實現(xiàn)動態(tài)數(shù)據(jù)源,需要的朋友可以參考下

動態(tài)數(shù)據(jù)源

在很多具體應用場景的時候,我們需要用到動態(tài)數(shù)據(jù)源的情況,比如多租戶的場景,系統(tǒng)登錄時需要根據(jù)用戶信息切換到用戶對應的數(shù)據(jù)庫。又比如業(yè)務A要訪問A數(shù)據(jù)庫,業(yè)務B要訪問B數(shù)據(jù)庫等,都可以使用動態(tài)數(shù)據(jù)源方案進行解決。接下來,我們就來講解如何實現(xiàn)動態(tài)數(shù)據(jù)源,以及在過程中剖析動態(tài)數(shù)據(jù)源背后的實現(xiàn)原理。

實現(xiàn)案例

本教程案例基于 Spring Boot + Mybatis + MySQL 實現(xiàn)。

數(shù)據(jù)庫設計

首先需要安裝好MySQL數(shù)據(jù)庫,新建數(shù)據(jù)庫 master,slave,分別創(chuàng)建用戶表,用來測試數(shù)據(jù)源,SQL腳本如下。

-- ----------------------------------------------------
-- 用戶
-- ----------------------------------------------------
-- Table structure for `sys_user`
-- ----------------------------------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
 `id` bigint NOT NULL AUTO_INCREMENT COMMENT '編號',
 `name` varchar(50) NOT NULL COMMENT '用戶名',
 `password` varchar(100) COMMENT '密碼',
 `salt` varchar(40) COMMENT '鹽',
 `email` varchar(100) COMMENT '郵箱',
 `mobile` varchar(100) COMMENT '手機號',
 `status` tinyint COMMENT '狀態(tài) 0:禁用 1:正常',
 `dept_id` bigint(20) COMMENT '機構ID',
 `create_by` varchar(50) COMMENT '創(chuàng)建人',
 `create_time` datetime COMMENT '創(chuàng)建時間',
 `last_update_by` varchar(50) COMMENT '更新人',
 `last_update_time` datetime COMMENT '更新時間',
 `del_flag` tinyint DEFAULT 0 COMMENT '是否刪除 -1:已刪除 0:正常',
 PRIMARY KEY (`id`),
 UNIQUE INDEX (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶';

新建工程

新建一個Spring Boot工程,最終代碼結構如下。

添加依賴

添加Spring Boot,Spring Aop,Mybatis,MySQL,Swagger相關依賴。Swagger方便用來測試接口。

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>

 <groupId>top.ivan.demo</groupId>
 <artifactId>springboot-dynamic-datasource</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>springboot-dynamic-datasource</name>
 <description>Demo project for Spring Boot</description>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.0.4.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
  <mybatis.spring.version>1.3.2</mybatis.spring.version>
  <swagger.version>2.8.0</swagger.version>
 </properties>

 <dependencies>
   <!-- spring boot -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>
  <!-- spring aop -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
  </dependency>
  <!-- mybatis -->
  <dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>${mybatis.spring.version}</version>
  </dependency>
  <!-- mysql -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
  </dependency>
  <!-- swagger -->
  <dependency>
   <groupId>io.springfox</groupId>
   <artifactId>springfox-swagger2</artifactId>
   <version>${swagger.version}</version>
  </dependency>
  <dependency>
   <groupId>io.springfox</groupId>
   <artifactId>springfox-swagger-ui</artifactId>
   <version>${swagger.version}</version>
  </dependency>
 </dependencies>

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

</project>

配置文件

修改配置文件,添加兩個數(shù)據(jù)源,可以是同一個主機地址的兩個數(shù)據(jù)庫master,slave,也可是兩個不同主機的地址,根據(jù)實際情況配置。

application.yml

spring:
 datasource:
 master:
  driver-class-name: com.mysql.jdbc.Driver
  type: com.zaxxer.hikari.HikariDataSource
  jdbcUrl: jdbc:mysql://127.0.0.1:3306/master?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8
  username: root
  password: 123
 slave:
  driver-class-name: com.mysql.jdbc.Driver
  type: com.zaxxer.hikari.HikariDataSource
  jdbcUrl: jdbc:mysql://127.0.0.1:3306/slave?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8
  username: root
  password: 123

啟動類

啟動類添加 exclude = {DataSourceAutoConfiguration.class}, 以禁用數(shù)據(jù)源默認自動配置。

數(shù)據(jù)源默認自動配置會讀取 spring.datasource.* 的屬性創(chuàng)建數(shù)據(jù)源,所以要禁用以進行定制。

@ComponentScan(basePackages = "com.louis.springboot") 是掃描范圍,都知道不用多說。

DynamicDatasourceApplication.java

package com.louis.springboot.dynamic.datasource;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

/**
 * 啟動器
 * @author Louis
 * @date Oct 31, 2018
 */
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) // 禁用數(shù)據(jù)源自動配置
@ComponentScan(basePackages = "com.louis.springboot")
public class DynamicDatasourceApplication {

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

數(shù)據(jù)源配置類

創(chuàng)建一個數(shù)據(jù)源配置類,主要做以下幾件事情:

1. 配置 dao,model,xml mapper文件的掃描路徑。

2. 注入數(shù)據(jù)源配置屬性,創(chuàng)建master、slave數(shù)據(jù)源。

3. 創(chuàng)建一個動態(tài)數(shù)據(jù)源,并裝入master、slave數(shù)據(jù)源。

4. 將動態(tài)數(shù)據(jù)源設置到SQL會話工廠和事務管理器。

如此,當進行數(shù)據(jù)庫操作時,就會通過我們創(chuàng)建的動態(tài)數(shù)據(jù)源去獲取要操作的數(shù)據(jù)源了。

package com.louis.springboot.dynamic.datasource.config;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
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 com.louis.springboot.dynamic.datasource.dds.DynamicDataSource;

/**
 * Mybatis配置
 * @author Louis
 * @date Oct 31, 2018
 */
@Configuration
@MapperScan(basePackages = {"com.louis.**.dao"}) // 掃描DAO
public class MybatisConfig {

 @Bean("master")
 @Primary
 @ConfigurationProperties(prefix = "spring.datasource.master")
 public DataSource master() {
  return DataSourceBuilder.create().build();
 }

 @Bean("slave")
 @ConfigurationProperties(prefix = "spring.datasource.slave")
 public DataSource slave() {
  return DataSourceBuilder.create().build();
 }

 @Bean("dynamicDataSource")
 public DataSource dynamicDataSource() {
  DynamicDataSource dynamicDataSource = new DynamicDataSource();
  Map<Object, Object> dataSourceMap = new HashMap<>(2);
  dataSourceMap.put("master", master());
  dataSourceMap.put("slave", slave());
  // 將 master 數(shù)據(jù)源作為默認指定的數(shù)據(jù)源
  dynamicDataSource.setDefaultDataSource(master());
  // 將 master 和 slave 數(shù)據(jù)源作為指定的數(shù)據(jù)源
  dynamicDataSource.setDataSources(dataSourceMap);
  return dynamicDataSource;
 }

 @Bean
 public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
  SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
  // 配置數(shù)據(jù)源,此處配置為關鍵配置,如果沒有將 dynamicDataSource作為數(shù)據(jù)源則不能實現(xiàn)切換
  sessionFactory.setDataSource(dynamicDataSource());
  sessionFactory.setTypeAliasesPackage("com.louis.**.model"); // 掃描Model
  PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  sessionFactory.setMapperLocations(resolver.getResources("classpath*:**/sqlmap/*.xml")); // 掃描映射文件
  return sessionFactory;
 }

 @Bean
 public PlatformTransactionManager transactionManager() {
  // 配置事務管理, 使用事務時在方法頭部添加@Transactional注解即可
  return new DataSourceTransactionManager(dynamicDataSource());
 }
}

動態(tài)數(shù)據(jù)源類

我們上一步把這個動態(tài)數(shù)據(jù)源設置到了SQL會話工廠和事務管理器,這樣在操作數(shù)據(jù)庫時就會通過動態(tài)數(shù)據(jù)源類來獲取要操作的數(shù)據(jù)源了。

動態(tài)數(shù)據(jù)源類集成了Spring提供的AbstractRoutingDataSource類,AbstractRoutingDataSource 中 獲取數(shù)據(jù)源的方法就是 determineTargetDataSource,而此方法又通過 determineCurrentLookupKey 方法獲取查詢數(shù)據(jù)源的key。

所以如果我們需要動態(tài)切換數(shù)據(jù)源,就可以通過以下兩種方式定制:

1. 覆寫 determineCurrentLookupKey 方法

通過覆寫 determineCurrentLookupKey 方法,從一個自定義的 DynamicDataSourceContextHolder.getDataSourceKey() 獲取數(shù)據(jù)源key值,這樣在我們想動態(tài)切換數(shù)據(jù)源的時候,只要通過  DynamicDataSourceContextHolder.setDataSourceKey(key)  的方式就可以動態(tài)改變數(shù)據(jù)源了。這種方式要求在獲取數(shù)據(jù)源之前,要先初始化各個數(shù)據(jù)源到 DynamicDataSource 中,我們案例就是采用這種方式實現(xiàn)的,所以在 MybatisConfig 中把master和slave數(shù)據(jù)源都事先初始化到DynamicDataSource 中。

2. 可以通過覆寫 determineTargetDataSource,因為數(shù)據(jù)源就是在這個方法創(chuàng)建并返回的,所以這種方式就比較自由了,支持到任何你希望的地方讀取數(shù)據(jù)源信息,只要最終返回一個 DataSource 的實現(xiàn)類即可。比如你可以到數(shù)據(jù)庫、本地文件、網絡接口等方式讀取到數(shù)據(jù)源信息然后返回相應的數(shù)據(jù)源對象就可以了。

DynamicDataSource.java

package com.louis.springboot.dynamic.datasource.dds;

import java.util.Map;

import javax.sql.DataSource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 動態(tài)數(shù)據(jù)源實現(xiàn)類
 * @author Louis
 * @date Oct 31, 2018
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
  
  
  /**
   * 如果不希望數(shù)據(jù)源在啟動配置時就加載好,可以定制這個方法,從任何你希望的地方讀取并返回數(shù)據(jù)源
   * 比如從數(shù)據(jù)庫、文件、外部接口等讀取數(shù)據(jù)源信息,并最終返回一個DataSource實現(xiàn)類對象即可
   */
  @Override
  protected DataSource determineTargetDataSource() {
    return super.determineTargetDataSource();
  }
  
  /**
   * 如果希望所有數(shù)據(jù)源在啟動配置時就加載好,這里通過設置數(shù)據(jù)源Key值來切換數(shù)據(jù),定制這個方法
   */
  @Override
  protected Object determineCurrentLookupKey() {
    return DynamicDataSourceContextHolder.getDataSourceKey();
  }
  
  /**
   * 設置默認數(shù)據(jù)源
   * @param defaultDataSource
   */
  public void setDefaultDataSource(Object defaultDataSource) {
    super.setDefaultTargetDataSource(defaultDataSource);
  }
  
  /**
   * 設置數(shù)據(jù)源
   * @param dataSources
   */
  public void setDataSources(Map<Object, Object> dataSources) {
    super.setTargetDataSources(dataSources);
    // 將數(shù)據(jù)源的 key 放到數(shù)據(jù)源上下文的 key 集合中,用于切換時判斷數(shù)據(jù)源是否有效
    DynamicDataSourceContextHolder.addDataSourceKeys(dataSources.keySet());
  }
}

數(shù)據(jù)源上下文

動態(tài)數(shù)據(jù)源的切換主要是通過調用這個類的方法來完成的。在任何想要進行切換數(shù)據(jù)源的時候都可以通過調用這個類的方法實現(xiàn)切換。比如系統(tǒng)登錄時,根據(jù)用戶信息調用這個類的數(shù)據(jù)源切換方法切換到用戶對應的數(shù)據(jù)庫。

主要方法介紹:

1. 切換數(shù)據(jù)源

在任何想要進行切換數(shù)據(jù)源的時候都可以通過調用這個類的方法實現(xiàn)切換。

  /**
   * 切換數(shù)據(jù)源
   * @param key
   */
  public static void setDataSourceKey(String key) {
    contextHolder.set(key);
  }

2. 重置數(shù)據(jù)源

將數(shù)據(jù)源重置回默認的數(shù)據(jù)源。默認數(shù)據(jù)源通過 DynamicDataSource.setDefaultDataSource(ds) 進行設置。

  /**
   * 重置數(shù)據(jù)源
   */
  public static void clearDataSourceKey() {
    contextHolder.remove();
  }

3. 獲取當前數(shù)據(jù)源key

  /**
   * 獲取數(shù)據(jù)源
   * @return
   */
  public static String getDataSourceKey() {
    return contextHolder.get();
  }

完整代碼如下

DynamicDataSourceContextHolder.java

package com.louis.springboot.dynamic.datasource.dds;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 動態(tài)數(shù)據(jù)源上下文
 * @author Louis
 * @date Oct 31, 2018
 */
public class DynamicDataSourceContextHolder {

  private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>() {
    /**
     * 將 master 數(shù)據(jù)源的 key作為默認數(shù)據(jù)源的 key
     */
    @Override
    protected String initialValue() {
      return "master";
    }
  };


  /**
   * 數(shù)據(jù)源的 key集合,用于切換時判斷數(shù)據(jù)源是否存在
   */
  public static List<Object> dataSourceKeys = new ArrayList<>();

  /**
   * 切換數(shù)據(jù)源
   * @param key
   */
  public static void setDataSourceKey(String key) {
    contextHolder.set(key);
  }

  /**
   * 獲取數(shù)據(jù)源
   * @return
   */
  public static String getDataSourceKey() {
    return contextHolder.get();
  }

  /**
   * 重置數(shù)據(jù)源
   */
  public static void clearDataSourceKey() {
    contextHolder.remove();
  }

  /**
   * 判斷是否包含數(shù)據(jù)源
   * @param key 數(shù)據(jù)源key
   * @return
   */
  public static boolean containDataSourceKey(String key) {
    return dataSourceKeys.contains(key);
  }
  
  /**
   * 添加數(shù)據(jù)源keys
   * @param keys
   * @return
   */
  public static boolean addDataSourceKeys(Collection<? extends Object> keys) {
    return dataSourceKeys.addAll(keys);
  }
}

注解式數(shù)據(jù)源

到這里,在任何想要動態(tài)切換數(shù)據(jù)源的時候,只要調用  DynamicDataSourceContextHolder.setDataSourceKey(key)  就可以完成了。

接下來我們實現(xiàn)通過注解的方式來進行數(shù)據(jù)源的切換,原理就是添加注解(如@DataSource(value="master")),然后實現(xiàn)注解切面進行數(shù)據(jù)源切換。

創(chuàng)建一個動態(tài)數(shù)據(jù)源注解,擁有一個value值,用于標識要切換的數(shù)據(jù)源的key。

DataSource.java

package com.louis.springboot.dynamic.datasource.dds;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 動態(tài)數(shù)據(jù)源注解
 * @author Louis
 * @date Oct 31, 2018
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
  
  /**
   * 數(shù)據(jù)源key值
   * @return
   */
  String value();
  
}

創(chuàng)建一個AOP切面,攔截帶 @DataSource 注解的方法,在方法執(zhí)行前切換至目標數(shù)據(jù)源,執(zhí)行完成后恢復到默認數(shù)據(jù)源。

DynamicDataSourceAspect.java

package com.louis.springboot.dynamic.datasource.dds;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 動態(tài)數(shù)據(jù)源切換處理器
 * @author Louis
 * @date Oct 31, 2018
 */
@Aspect
@Order(-1) // 該切面應當先于 @Transactional 執(zhí)行
@Component
public class DynamicDataSourceAspect {
  
  /**
   * 切換數(shù)據(jù)源
   * @param point
   * @param dataSource
   */
  @Before("@annotation(dataSource))")
  public void switchDataSource(JoinPoint point, DataSource dataSource) {
    if (!DynamicDataSourceContextHolder.containDataSourceKey(dataSource.value())) {
      System.out.println("DataSource [{}] doesn't exist, use default DataSource [{}] " + dataSource.value());
    } else {
      // 切換數(shù)據(jù)源
      DynamicDataSourceContextHolder.setDataSourceKey(dataSource.value());
      System.out.println("Switch DataSource to [" + DynamicDataSourceContextHolder.getDataSourceKey()
        + "] in Method [" + point.getSignature() + "]");
    }
  }

  /**
   * 重置數(shù)據(jù)源
   * @param point
   * @param dataSource
   */
  @After("@annotation(dataSource))")
  public void restoreDataSource(JoinPoint point, DataSource dataSource) {
    // 將數(shù)據(jù)源置為默認數(shù)據(jù)源
    DynamicDataSourceContextHolder.clearDataSourceKey();
    System.out.println("Restore DataSource to [" + DynamicDataSourceContextHolder.getDataSourceKey() 
      + "] in Method [" + point.getSignature() + "]");
  }
}

到這里,動態(tài)數(shù)據(jù)源相關的處理代碼就完成了。

編寫用戶業(yè)務代碼

接下來編寫用戶查詢業(yè)務代碼,用來進行測試,只需添加一個查詢接口即可。

編寫一個控制器,包含兩個查詢方法,分別注解 master 和 slave 數(shù)據(jù)源。

SysUserController.java
package com.louis.springboot.dynamic.datasource.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.louis.springboot.dynamic.datasource.dds.DataSource;
import com.louis.springboot.dynamic.datasource.service.SysUserService;
/**
 * 用戶控制器
 * @author Louis
 * @date Oct 31, 2018
 */
@RestController
@RequestMapping("user")
public class SysUserController {
  @Autowired
  private SysUserService sysUserService;
  @DataSource(value="master")
  @PostMapping(value="/findAll")
  public Object findAll() {
    return sysUserService.findAll();
  }
  @DataSource(value="slave")
  @PostMapping(value="/findAll2")
  public Object findAll2() {
    return sysUserService.findAll();
  }
}

下面是正常的業(yè)務代碼,沒有什么好說明的,直接貼代碼了。

SysUser.java
public class SysUser {
  private Long id;
  private String name;
  private String password;
  private String salt;
  private String email;
  private String mobile;
  private Byte status;
  private Long deptId;
  private String deptName;
  private Byte delFlag;
  private String createBy;
  private Date createTime;
  private String lastUpdateBy;
  private Date lastUpdateTime;
  ...setter and getter
}
SysUserMapper.java
package com.louis.springboot.dynamic.datasource.dao;
import java.util.List;
import com.louis.springboot.dynamic.datasource.model.SysUser;
public interface SysUserMapper {
  int deleteByPrimaryKey(Long id);
  int insert(SysUser record);
  int insertSelective(SysUser record);
  SysUser selectByPrimaryKey(Long id);
  int updateByPrimaryKeySelective(SysUser record);
  int updateByPrimaryKey(SysUser record);
  List<SysUser> findAll();
}

SysUserMapper.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.louis.springboot.dynamic.datasource.dao.SysUserMapper">
 <resultMap id="BaseResultMap" type="com.louis.springboot.dynamic.datasource.model.SysUser">
  <id column="id" jdbcType="BIGINT" property="id" />
  <result column="name" jdbcType="VARCHAR" property="name" />
  <result column="password" jdbcType="VARCHAR" property="password" />
  <result column="salt" jdbcType="VARCHAR" property="salt" />
  <result column="email" jdbcType="VARCHAR" property="email" />
  <result column="mobile" jdbcType="VARCHAR" property="mobile" />
  <result column="status" jdbcType="TINYINT" property="status" />
  <result column="dept_id" jdbcType="BIGINT" property="deptId" />
  <result column="create_by" jdbcType="BIGINT" property="createBy" />
  <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
  <result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
  <result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
  <result column="del_flag" jdbcType="TINYINT" property="delFlag" />
 </resultMap>
 <sql id="Base_Column_List">
  id, name, password, salt, email, mobile, status, dept_id, create_by, create_time, 
  last_update_by, last_update_time, del_flag
 </sql>
 <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
  select 
  <include refid="Base_Column_List" />
  from sys_user
  where id = #{id,jdbcType=BIGINT}
 </select>
 <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
  delete from sys_user
  where id = #{id,jdbcType=BIGINT}
 </delete>
 <insert id="insert" parameterType="com.louis.springboot.dynamic.datasource.model.SysUser">
  insert into sys_user (id, name, password, 
   salt, email, mobile, 
   status, dept_id, create_by, 
   create_time, last_update_by, last_update_time, 
   del_flag)
  values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
   #{salt,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, 
   #{status,jdbcType=TINYINT}, #{deptId,jdbcType=BIGINT}, #{createBy,jdbcType=BIGINT}, 
   #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, 
   #{delFlag,jdbcType=TINYINT})
 </insert>
 <insert id="insertSelective" parameterType="com.louis.springboot.dynamic.datasource.model.SysUser">
  insert into sys_user
  <trim prefix="(" suffix=")" suffixOverrides=",">
   <if test="id != null">
    id,
   </if>
   <if test="name != null">
    name,
   </if>
   <if test="password != null">
    password,
   </if>
   <if test="salt != null">
    salt,
   </if>
   <if test="email != null">
    email,
   </if>
   <if test="mobile != null">
    mobile,
   </if>
   <if test="status != null">
    status,
   </if>
   <if test="deptId != null">
    dept_id,
   </if>
   <if test="createBy != null">
    create_by,
   </if>
   <if test="createTime != null">
    create_time,
   </if>
   <if test="lastUpdateBy != null">
    last_update_by,
   </if>
   <if test="lastUpdateTime != null">
    last_update_time,
   </if>
   <if test="delFlag != null">
    del_flag,
   </if>
  </trim>
  <trim prefix="values (" suffix=")" suffixOverrides=",">
   <if test="id != null">
    #{id,jdbcType=BIGINT},
   </if>
   <if test="name != null">
    #{name,jdbcType=VARCHAR},
   </if>
   <if test="password != null">
    #{password,jdbcType=VARCHAR},
   </if>
   <if test="salt != null">
    #{salt,jdbcType=VARCHAR},
   </if>
   <if test="email != null">
    #{email,jdbcType=VARCHAR},
   </if>
   <if test="mobile != null">
    #{mobile,jdbcType=VARCHAR},
   </if>
   <if test="status != null">
    #{status,jdbcType=TINYINT},
   </if>
   <if test="deptId != null">
    #{deptId,jdbcType=BIGINT},
   </if>
   <if test="createBy != null">
    #{createBy,jdbcType=BIGINT},
   </if>
   <if test="createTime != null">
    #{createTime,jdbcType=TIMESTAMP},
   </if>
   <if test="lastUpdateBy != null">
    #{lastUpdateBy,jdbcType=BIGINT},
   </if>
   <if test="lastUpdateTime != null">
    #{lastUpdateTime,jdbcType=TIMESTAMP},
   </if>
   <if test="delFlag != null">
    #{delFlag,jdbcType=TINYINT},
   </if>
  </trim>
 </insert>
 <update id="updateByPrimaryKeySelective" parameterType="com.louis.springboot.dynamic.datasource.model.SysUser">
  update sys_user
  <set>
   <if test="name != null">
    name = #{name,jdbcType=VARCHAR},
   </if>
   <if test="password != null">
    password = #{password,jdbcType=VARCHAR},
   </if>
   <if test="salt != null">
    salt = #{salt,jdbcType=VARCHAR},
   </if>
   <if test="email != null">
    email = #{email,jdbcType=VARCHAR},
   </if>
   <if test="mobile != null">
    mobile = #{mobile,jdbcType=VARCHAR},
   </if>
   <if test="status != null">
    status = #{status,jdbcType=TINYINT},
   </if>
   <if test="deptId != null">
    dept_id = #{deptId,jdbcType=BIGINT},
   </if>
   <if test="createBy != null">
    create_by = #{createBy,jdbcType=BIGINT},
   </if>
   <if test="createTime != null">
    create_time = #{createTime,jdbcType=TIMESTAMP},
   </if>
   <if test="lastUpdateBy != null">
    last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
   </if>
   <if test="lastUpdateTime != null">
    last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
   </if>
   <if test="delFlag != null">
    del_flag = #{delFlag,jdbcType=TINYINT},
   </if>
  </set>
  where id = #{id,jdbcType=BIGINT}
 </update>
 <update id="updateByPrimaryKey" parameterType="com.louis.springboot.dynamic.datasource.model.SysUser">
  update sys_user
  set name = #{name,jdbcType=VARCHAR},
   password = #{password,jdbcType=VARCHAR},
   salt = #{salt,jdbcType=VARCHAR},
   email = #{email,jdbcType=VARCHAR},
   mobile = #{mobile,jdbcType=VARCHAR},
   status = #{status,jdbcType=TINYINT},
   dept_id = #{deptId,jdbcType=BIGINT},
   create_by = #{createBy,jdbcType=BIGINT},
   create_time = #{createTime,jdbcType=TIMESTAMP},
   last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
   last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
   del_flag = #{delFlag,jdbcType=TINYINT}
  where id = #{id,jdbcType=BIGINT}
 </update>
 <select id="findAll" resultMap="BaseResultMap">
  select 
  <include refid="Base_Column_List" />
  from sys_user
 </select>
</mapper>

SysUserService.java

package com.louis.springboot.dynamic.datasource.service;
import java.util.List;
import com.louis.springboot.dynamic.datasource.model.SysUser;
/**
 * 用戶管理
 * @author Louis
 * @date Oct 31, 2018
 */
public interface SysUserService {
  /**
   * 查找全部用戶信息
   * @return
   */
  List<SysUser> findAll();
}
SysUserServiceImpl.java
package com.louis.springboot.dynamic.datasource.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.louis.springboot.dynamic.datasource.dao.SysUserMapper;
import com.louis.springboot.dynamic.datasource.model.SysUser;
import com.louis.springboot.dynamic.datasource.service.SysUserService;
@Service
public class SysUserServiceImpl implements SysUserService {
  @Autowired
  private SysUserMapper sysUserMapper;
  /**
   * 查找全部用戶信息
   * @return
   */
  public List<SysUser> findAll() {
    return sysUserMapper.findAll();
  }
}

測試效果

啟動系統(tǒng),訪問  http://localhost:8080/swagger-ui.html ,分別測試兩個接口,成功返回數(shù)據(jù)。

user/findAll (master數(shù)據(jù)源)

 

user/findAll2 (slave數(shù)據(jù)源)

源碼下載

碼云:https://gitee.com/liuge1988/spring-boot-demo.git

總結

以上所述是小編給大家介紹的Spring Boot + Mybatis 實現(xiàn)動態(tài)數(shù)據(jù)源案例分析,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

相關文章

  • MyBatis-Plus標簽@TableField之fill自動填充方式

    MyBatis-Plus標簽@TableField之fill自動填充方式

    這篇文章主要介紹了MyBatis-Plus標簽@TableField之fill自動填充方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 基于mybatis注解動態(tài)sql中foreach工具的方法

    基于mybatis注解動態(tài)sql中foreach工具的方法

    這篇文章主要介紹了mybatis注解動態(tài)sql中foreach工具方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java 對數(shù)和指數(shù)計算方式

    java 對數(shù)和指數(shù)計算方式

    這篇文章主要介紹了java 對數(shù)和指數(shù)計算方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java 字符串轉float運算 float轉字符串的方法

    Java 字符串轉float運算 float轉字符串的方法

    今天小編就為大家分享一篇Java 字符串轉float運算 float轉字符串的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • SpringBoot項目設置斷點debug調試無效忽略web.xml問題的解決

    SpringBoot項目設置斷點debug調試無效忽略web.xml問題的解決

    這篇文章主要介紹了SpringBoot項目設置斷點debug調試無效忽略web.xml問題的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Java微信跳一跳操作指南

    Java微信跳一跳操作指南

    這篇文章主要為大家詳細介紹了Java微信跳一跳操作指南,通過adb來控制手機進行操作,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • ES結合java代碼聚合查詢詳細示例

    ES結合java代碼聚合查詢詳細示例

    es查詢有一個很常用的一種叫聚合查詢,相當于mysql中的分組group by 后拿各組數(shù)量進行統(tǒng)計,實現(xiàn)起來也是很簡單,下面這篇文章主要給大家介紹了關于ES結合java代碼聚合查詢的相關資料,需要的朋友可以參考下
    2023-05-05
  • SpringBoot的兩種啟動方式原理解析(配置方案)

    SpringBoot的兩種啟動方式原理解析(配置方案)

    本文介紹了Spring?Boot中兩種啟動方式,使用內置Tomcat啟動和使用外置Tomcat部署,在使用內置Tomcat啟動時,可以通過IDEA的main函數(shù)啟動,也可以使用nohup命令在后臺運行,這篇文章主要介紹了SpringBoot的兩種啟動方式原理?,需要的朋友可以參考下
    2025-01-01
  • 通過Spring層面進行事務回滾的實現(xiàn)

    通過Spring層面進行事務回滾的實現(xiàn)

    本文主要介紹了通過Spring層面進行事務回滾的實現(xiàn),包括聲明式事務和編程式事務,具有一定的參考價值,感興趣的可以了解一下
    2025-04-04
  • 你知道在Java中Integer和int的這些區(qū)別嗎?

    你知道在Java中Integer和int的這些區(qū)別嗎?

    最近面試,突然被問道,說一下Integer和int的區(qū)別.額…可能平時就知道寫一些業(yè)務代碼,包括面試的一些Spring源碼等,對于這種特別基礎的反而忽略了,導致面試的時候突然被問到反而不知道怎么回答了.哎,還是乖乖再看看底層基礎,順帶記錄一下把 ,需要的朋友可以參考下
    2021-06-06

最新評論

百色市| 堆龙德庆县| 游戏| 织金县| 南城县| 牟定县| 兴和县| 稷山县| 天津市| 吉木乃县| 阜阳市| 阳山县| 连州市| 慈溪市| 林甸县| 左权县| 东丽区| 连平县| 崇明县| 抚松县| 平利县| 孝感市| 和平区| 韶山市| 珲春市| 依安县| 广灵县| 梓潼县| 蚌埠市| 邛崃市| 闽侯县| 民和| 四会市| 辽源市| 上栗县| 佛教| 无锡市| 长沙县| 江都市| 梁山县| 奎屯市|