SpringBoot + Mybatis-Plus 實現多數據源簡單示例


1. 簡介

  在單體項目中,經常出現想要訪問多個數據源的情況,或者因為某些性能瓶頸,將大數據量的業務表分離到另一個庫等情況。
  實現多數據源的方案有很多,Mybatis-Plus提供了非常簡單的實現方案,以此為例。

2. 示例代碼

  • 創建數據庫及初始化表數據
CREATE DATABASE `db_master`;

USE `db_master`;

--
-- Table structure for table `user`
--
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

--
-- Dumping data for table `user`
--
LOCK TABLES `user` WRITE;
INSERT INTO `user` VALUES (1,'master',18);
UNLOCK TABLES;

--
-- Current Database: `db_slave_1`
--
CREATE DATABASE `db_slave_1`;

USE `db_slave_1`;

--
-- Table structure for table `user`
--
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


--
-- Dumping data for table `user`
--
LOCK TABLES `user` WRITE;
INSERT INTO `user` VALUES (1,'slave_1',20);
UNLOCK TABLES;

--
-- Current Database: `db_slave_2`
--
CREATE DATABASE `db_slave_2` ;

USE `db_slave_2`;

--
-- Table structure for table `user`
--
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

--
-- Dumping data for table `user`
--
LOCK TABLES `user` WRITE;
INSERT INTO `user` VALUES (1,'slave_2',22);
UNLOCK TABLES;
  • 創建項目
  • 修改pom.xml
<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.0</modelVersion>
	<groupId>com.c3stones</groupId>
	<artifactId>spring-boot-dynamic-datasource-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-dynamic-datasource-demo</name>
	<description>Spring Boot Dynamic Datasource Demo</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.8.RELEASE</version>
		<relativePath />
	</parent>

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

	<dependencies>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.3.2</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
			<version>3.1.1</version>
		</dependency>
		<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>
		</dependency>
	</dependencies>

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

</project>
  • 添加配置文件application.yml
      可配置多數據源。
spring:
  datasource:
    dynamic:
      primary: master # 設置默認的數據源或者數據源組,默認值即為master
      strict: false # 設置嚴格模式,默認false不啟動。啟動后在未匹配到指定數據源時候回拋出異常,不啟動會使用默認數據源。
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/db_master
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_1:
          url: jdbc:mysql://127.0.0.1:3306/db_slave_1
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: jdbc:mysql://127.0.0.1:3306/db_slave_2
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
          
mybatis-plus:
   mapper-locations: classpath:/mapper/*/*Mapper.xml
   configuration:
      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • 創建實體
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

/**
 * 用戶Entity
 * @author CL
 *
 */
@TableName(value = "user")
public class User {

	/**
	 * ID
	 */
	@TableId(value = "id", type = IdType.AUTO)
	private Long id;

	/**
	 * 用戶名稱
	 */
	private String username;

	/**
	 * 年齡
	 */
	private int age;

	public User() {
		super();
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", age=" + age + "]";
	}
	
}
  • 創建Mapper
import org.apache.ibatis.annotations.Mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.c3stones.entity.User;

/**
 * 用戶Mapper
 * 
 * @author CL
 *
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

}
  • 在resource目錄下創建mapper文件夾並添加Mapper.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.c3stones.mapper.UserMapper">

</mapper>
  • 創建Service
import java.util.List;

import com.baomidou.mybatisplus.extension.service.IService;
import com.c3stones.entity.User;

/**
 * 用戶Service
 * 
 * @author CL
 *
 */
public interface UserService extends IService<User> {

	/**
	 * 查詢全部用戶
	 * 
	 * @return 用戶列表
	 */
	List<User> selectMasterAll();

	/**
	 * 查詢全部用戶
	 * 
	 * @return 用戶列表
	 */
	List<User> selectSlave1All();

	/**
	 * 查詢全部用戶
	 * 
	 * @return 用戶列表
	 */
	List<User> selectSlave2All();

}
  • 創建Service實現
      注解@DS配置當前Service的數據源,建議將此注解添加到Service的類或方法上,注意:方法上的優先級高於類
import java.util.List;

import org.springframework.stereotype.Service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.c3stones.entity.User;
import com.c3stones.mapper.UserMapper;
import com.c3stones.service.UserService;

/**
 * 用戶Service實現
 * 
 * @author CL
 *
 */
@Service
@DS("master")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

	/**
	 * 查詢全部用戶
	 * 
	 * @return 用戶列表
	 */
	@Override
	public List<User> selectMasterAll() {
		return baseMapper.selectList(new QueryWrapper<>());
	}

	/**
	 * 查詢全部用戶
	 * 
	 * @return 用戶列表
	 */
	@DS("slave_1")
	@Override
	public List<User> selectSlave1All() {
		return baseMapper.selectList(new QueryWrapper<>());
	}

	/**
	 * 查詢全部用戶
	 * 
	 * @return 用戶列表
	 */
	@DS("slave_2")
	@Override
	public List<User> selectSlave2All() {
		return baseMapper.selectList(new QueryWrapper<>());
	}

}
  • 創建啟動類
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 啟動類
 * 
 * @author CL
 *
 */
@SpringBootApplication
public class Application {

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

3. 單元測試

  • 創建單元測試類
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.c3stones.Application;
import com.c3stones.entity.User;
import com.c3stones.service.UserService;

/**
 * 用戶Service測試
 * 
 * @author CL
 *
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { Application.class })
public class UserServiceImplTest {

	@Autowired
	private UserService userService;

	/**
	 * 測試查詢master庫用戶信息
	 */
	@Test
	public void selectMasterAllTest() {
		List<User> list = userService.selectMasterAll();
		list.forEach(System.out::println);
	}

	/**
	 * 測試查詢slave_1庫用戶信息
	 */
	@Test
	public void selectSlave1AllTest() {
		List<User> list = userService.selectSlave1All();
		list.forEach(System.out::println);
	}

	/**
	 * 測試查詢slave_2庫用戶信息
	 */
	@Test
	public void selectSlave2AllTest() {
		List<User> list = userService.selectSlave2All();
		list.forEach(System.out::println);
	}

}

  單元測試時仔細觀察控制台日志,及結果打印信息。

4. 項目地址

  spring-boot-dynamic-datasource-demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM