SpringBoot 实现mysql数据库读写分离

写在前面

本文用的linux是centos8,其他linux可能部分指令不一样

适用工作场景:当数据量比较大时,通常写入数据速度是比较慢的,这时我们利用多台服务器进行读写分离,加快数据查询速度。

下面采用两个虚拟机(linux)模拟2个主从数据库

两个虚拟机是克隆出来的,所以数据库的uuid相同,需要需改一下:

1、mysql 搭建一主多从数据库集群

1.1、主库配置

先查看mysql的3306端口开放没有

[root@localhost ~]# sudo netstat -aptn
# 或者直接关闭防火墙
[root@localhost ~]# systemctl stop firewalld

接下来新建用户uuu,并分配权限:

mysql> CREATE USER 'uuu'@'%' IDENTIFIED BY '123456';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'uuu'@'%';
mysql> flush privileges;                                        #刷新权限

修改 mysql 配置文件my.cnf,开启二进制日志:

[root@localhost ~]# cd /etc
[root@localhost etc]# ls
[root@localhost etc]# vim /etc/my.cnf

# 下面是my.cnf中添加的内容
[mysqld]
server-id=1
log-bin=master-bin
log-bin-index=master-bin.index
binlog-do-db=iii



# 保存后重启mysql服务
[root@localhost etc]# service mysqld restart     
[root@localhost etc]# mysql -uroot -p                        # 进入mysql,查看状态
mysql> show master status;                                   # 将查询得到的File 、Position这两个值记录下来,从库配置的时候需要填写

注意:
1、每次重启MySQL,File 、Position这两个值都可能改变
2、在my.cnf中添加的内容里面最后一句:binlog-do-db=iii,表示只同步iii这个库。并且iii这个库不能在设置主从同步之前创建。限定仅配置哪些表的语句如下:

不同步哪些数据库 (下面这些写在server-id=1下面即可)
binlog-ignore-db = mysql
binlog-ignore-db = test
binlog-ignore-db = information_schema
只同步哪些数据库,除此之外,其他不同步
binlog-do-db = iii

1.2、从库配置

[root@localhost ~]# vim /etc/my.cnf                   # 修改 mysql 配置文件开启二进制日志
 
# 新增部分如下:
[mysqld]
server-id=2
relay-log-index=slave-relay-bin.index
relay-log=slave-relay-bin


[root@localhost ~]# service mysqld restart             # 重启mysql
[root@localhost ~]# mysql -uroot -p
mysql> SHOW GLOBAL VARIABLES like 'server\_id';        # 查看server-id=2有没有配置成功
mysql> CHANGE MASTER TO
         MASTER_HOST='192.168.10.1',
         MASTER_USER='root',
         MASTER_PASSWORD='root',
         MASTER_LOG_FILE='master-bin.000001',
         MASTER_LOG_POS=120;
mysql> start slave;                                    # 开启备份
mysql> show slave status\G                             # 查看状态

查看状态Slave_IO_Running 和 Slave_SQL_Running 都为 yes表示正在同步。
在这里插入图片描述
配置完成之后,在主库里面建库、建表、插入数据,从库里面也会有对应的数据,注意不要往主从配置之前已经存在的库中加数据,否则会报错。
其他相关指令:

mysql> stop slave;                        # 停止主从备份
mysql> reset slave all;                   # 删除之前执行的语句

1.3、遇到的问题

问题1:如果Slave_IO_Running为Connecting,可能的原因有下面几个:

1.网络不通
2.账户密码错误
3.防火墙
4.mysql配置文件问题
5.连接服务器时语法
6.主服务器mysql权限

其他问题:

参考文章:https://blog.csdn.net/weixin_39744606/article/details/113397916
参考文章:https://blog.csdn.net/weixin_39716971/article/details/113592178

2、代码层面进行读写分离

代码环境: springboot+mybatis+druib 连接池

如果springboot项目访问不了数据库,考虑一下是不是linux防火墙的问题,可以先把防火墙关闭了

项目git仓库地址:https://gitee.com/YH0100/springTO2mysql

2.1、搭建springboot环境

新建项目之前保证已建库test、建表user(id,name)

先新建一个springboot项目,并连接数据库获取数据
在这里插入图片描述
application.yaml

# 应用名称
spring.application.name: mysql2demo
server.port: 8080

#MyBatis
mybatis:
  mapper-locations: classpath:mappers/*.xml
  type-aliases-package: com.example.mysql2demo.entity

spring:
  datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://192.168.10.129:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
     username: root
     password: Lalala123!

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>mysql2demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mysql2demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>
    <dependencies>
        <!--SpringBoot集成Aop起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--SpringBoot集成Jdbc起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--SpringBoot集成WEB起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--mybatis集成SpringBoot起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <!--MySQL驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--SpringBoot单元测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.example.mysql2demo.Mysql2demoApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

UserMapper.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.example.mysql2demo.dao.UserDao">
    <insert id="save" parameterType="com.example.mysql2demo.entity.User">
        insert into user(id,name)
        values (#{id},#{name})
    </insert>
    <select id="getById" resultType="com.example.mysql2demo.entity.User" parameterType="int">
        select * from user where id=#{id};
    </select>
</mapper>

Mysql2demoApplication.java

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

@SpringBootApplication
@MapperScan(basePackages = {"com.example.mysql2demo.dao"})
public class Mysql2demoApplication {

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

}

User.java

public class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

UserDao.java

import com.example.mysql2demo.entity.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserDao {
    public User getById(int id);
    public void save(User user);
}

UserService.java

import com.example.mysql2demo.entity.User;

public interface UserService {
    public User getById(int id);
    public void save(User user);
}

UserServiceImpl.java

import com.example.mysql2demo.dao.UserDao;
import com.example.mysql2demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public User getById(int id) {
        return userDao.getById(id);
    }


    @Override
    public void save(User user) {
        userDao.save(user);
    }
}

UserController.java

import com.example.mysql2demo.entity.User;
import com.example.mysql2demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/get/{id}")
    public User queryById(@PathVariable("id") int id){
        return userService.getById(id);
    }

    @RequestMapping("/save")
    public void addDept(User user){
        userService.save(user);
    }
}

2.1、配置多个数据源

如何切换数据源:spring 支持多数据源,多个 datasource 放在一个 HashMapTargetDataSource中,通过dertermineCurrentLookupKey 来决定要使用哪个数据源。

下面是项目目录结构
在这里插入图片描述
第一步:修改yaml配置文件,写入多个数据源配置
application.yml

spring:
  datasource:
    master:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.10.129:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
      username: root
      password: Lalala123!
    slave1:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.10.128:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
      username: root
      password: Lalala123!
    slave2:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.10.128:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
      username: root
      password: Lalala123!

#MyBatis
mybatis:
  mapper-locations: classpath:mappers/*.xml
  type-aliases-package: com.example.mysql2demo.entity

第二步:从yaml中获取数据源配置,返回DataSource
DBTypeEnum.java

/**
 * 定义一个枚举来代表这三个数据源
 */

public enum DBTypeEnum {
    MASTER, SLAVE1, SLAVE2;
}

DataSourceConfig.java

import org.springframework.beans.factory.annotation.Qualifier;
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 javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 关于数据源配置,参考SpringBoot官方文档第79章《Data Access》
 * 79. Data Access
 * 79.1 Configure a Custom DataSource
 * 79.2 Configure Two DataSources
 * 这里配置了4个数据源,1个master,2两个slave,1个路由数据源。前3个数据源都是为了生成第4个数据源,而且后续我们只用这最后一个路由数据源。
 */

@Configuration
public class DataSourceConfig {

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

    @Bean
    @ConfigurationProperties("spring.datasource.slave1")
    public DataSource slave1DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.slave2")
    public DataSource slave2DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public DataSource myRoutingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                          @Qualifier("slave1DataSource") DataSource slave1DataSource,
                                          @Qualifier("slave2DataSource") DataSource slave2DataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DBTypeEnum.MASTER, masterDataSource);
        targetDataSources.put(DBTypeEnum.SLAVE1, slave1DataSource);
        targetDataSources.put(DBTypeEnum.SLAVE2, slave2DataSource);
        MyRoutingDataSource myRoutingDataSource = new MyRoutingDataSource();
        myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);
        myRoutingDataSource.setTargetDataSources(targetDataSources);
        return myRoutingDataSource;
    }

}

第三步:mybatis配置类(把数据源的选择写成我们自己的类myRoutingDataSource)
myRoutingDataSource.java

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

/**
 * 获取路由key
 */
public class MyRoutingDataSource extends AbstractRoutingDataSource {
    @Nullable
    @Override
    protected Object determineCurrentLookupKey() {
        return DBContextHolder.get();
    }
}

MyBatisConfig.java

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * 由于Spring容器中现在有4个数据源,所以我们需要为事务管理器和MyBatis手动指定一个明确的数据源。
 */
@EnableTransactionManagement
@Configuration
public class MyBatisConfig {

    @Resource(name = "myRoutingDataSource")
    private DataSource myRoutingDataSource;

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(myRoutingDataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public PlatformTransactionManager platformTransactionManager() {
        return new DataSourceTransactionManager(myRoutingDataSource);
    }
}

第四步:使用AOP拦截对应service方法名,去选择对应的数据源

先通过ThreadLocal将数据源设置到每个线程上下文中
DBContextHolder.java

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 通过ThreadLocal将数据源设置到每个线程上下文中
 */
public class DBContextHolder {

    private static final ThreadLocal<DBTypeEnum> contextHolder = new ThreadLocal<>();

    private static final AtomicInteger counter = new AtomicInteger(-1);

    public static void set(DBTypeEnum dbType) {
        contextHolder.set(dbType);
    }

    public static DBTypeEnum get() {
        return contextHolder.get();
    }

    public static void master() {
        set(DBTypeEnum.MASTER);
        System.out.println("切换到master");
    }

    public static void slave() {
        System.out.println("正在选择使用哪个读库");
        //  轮询
        int index = counter.getAndIncrement() % 2;
        if (counter.get() > 9999) {
            counter.set(-1);
        }
        if (index == 0) {
            set(DBTypeEnum.SLAVE1);
            System.out.println("切换到slave1");
        }else {
            set(DBTypeEnum.SLAVE2);
            System.out.println("切换到slave2");
        }
    }

}

再使用aop拦截service实现类的方法
DataSourceAop.java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 默认情况下,所有的查询都走从库,插入/修改/删除走主库。我们通过方法名来区分操作类型(CRUD)
 */
@Aspect
@Component
public class DataSourceAop {
    // 拦截Master、select开头的方法、find开头的方法、get...
    @Pointcut("!@annotation(com.example.mysql2demo.annotation.Master) " +
            "&& (execution(* com.example.mysql2demo.service.*.select*(..)) " +
            "|| execution(* com.example.mysql2demo.service..*.find*(..))" +
            "|| execution(* com.example.mysql2demo.service..*.get*(..)))")
    public void readPointcut() {

    }

    // 拦截Master、save、add...等开头的方法
    @Pointcut("@annotation(com.example.mysql2demo.annotation.Master) " +
            "|| execution(* com.example.mysql2demo.service..*.save*(..)) " +
            "|| execution(* com.example.mysql2demo.service..*.add*(..)) " +
            "|| execution(* com.example.mysql2demo.service..*.update*(..)) " +
            "|| execution(* com.example.mysql2demo.service..*.edit*(..)) " +
            "|| execution(* com.example.mysql2demo..*.delete*(..)) " +
            "|| execution(* com.example.mysql2demo..*.remove*(..))")
    public void writePointcut() {

    }

    @Before("readPointcut()")
    public void read() {
        System.out.println("读操作");
        DBContextHolder.slave();
    }

    @Before("writePointcut()")
    public void write() {
        System.out.println("写操作");
        DBContextHolder.master();
    }


    /**
     * 另一种写法:if...else...  判断哪些需要读从数据库,其余的走主数据库
     */
//    @Before("execution(* com.cjs.example.service.impl.*.*(..))")
//    public void before(JoinPoint jp) {
//        String methodName = jp.getSignature().getName();
//
//        if (StringUtils.startsWithAny(methodName, "get", "select", "find")) {
//            DBContextHolder.slave();
//        }else {
//            DBContextHolder.master();
//        }
//    }




// aop相关知识:
//    在Spring AOP中,有3个常用的概念,Advices、Pointcut、Advisor,解释如下,
//
//    Advices:表示一个method执行前或执行后的动作。
//
//    Pointcut:表示根据method的名字或者正则表达式去拦截一个method。
//
//    Advisor:Advice和Pointcut组成的独立的单元,并且能够传给proxy factory 对象。
}

在service实现类上使用@Master注解,表示使用主库
在这里插入图片描述

2.3、测试

需要注意的是所有能拦截的方法都在DataSourceAop里面拦截,所以方法名不对不会拦截,会使用默认数据源

启动项目,访问
在这里插入图片描述
在这里插入图片描述
后台
在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Spring Boot可以通过配置数据源来实现MySQL分离。 1. 首先需要配置主数据源和从数据源,在application.properties中配置好主数据源的URL、用户名、密码等信息,并在从数据源中配置相同的信息。 2. 然后在配置类中配置数据源的负载均衡策略,例如采用轮询策略。 3. 最后在需要切换数据源的地方使用 @Transactional(readOnly = true) 设置当前事务为只事务,这样就会使用从数据源进行操作。 具体实现可以参考 Spring Boot 的文档或者第三方模块如 druid-spring-boot-starter。 ### 回答2: 在Spring Boot中实现MySQL分离可以通过以下步骤来完成: 1. 配置MySQL主从复制:首先,需要在服务器上设置好MySQL主从复制,确保主数据库和从数据库之间的数据同步。可以使用binlog日志来实现主从复制。 2. 配置数据源:在Spring Boot的application.properties(或application.yml)文件中,配置两个数据源,一个用于操作,一个用于操作。分别配置主数据库和从数据库的连接信息。 3. 设置数据源路由:使用Spring AOP(面向切面编程)和注解进行数据源的动态切换。可以定义一个切点,用于拦截数据库的访问操作,并根据具体的业务需求切换到对应的数据源。 4. 编分离的数据源配置类:在Spring Boot中,可以自定义一个分离的数据源配置类,用于管理数据源的切换。该类可以使用ThreadLocal来保存当前线程使用的数据源,然后根据具体的业务需求来选择具体的数据源。 5. 配置数据源切换的拦截器:在Spring Boot的配置文件中,配置AOP拦截器,将数据源的切换逻辑应用到具体的业务代码中。 6. 测试分离效果:可以编一些测试用例,测试操作是否成功切换到了对应的数据源。 需要注意的是,分离只能解决数据库性能问题,并不能解决数据库的高可用问题。因此,在实际生产环境中,还需要考虑到主从数据库之间的数据同步延迟和故障切换等问题。 ### 回答3: 在Spring Boot中实现MySQL分离,可以采用以下步骤: 1. 引入相关依赖:需要在pom.xml文件中引入spring-boot-starter-data-jpa和mysql-connector-java相关依赖。 2. 配置数据源:在application.properties文件中配置主从数据源的连接信息。例如: ``` spring.datasource.url=jdbc:mysql://主数据库IP:主数据库端口/主数据库名称 spring.datasource.username=主数据库用户名 spring.datasource.password=主数据库密码 spring.datasource.slave.url=jdbc:mysql://从数据库IP:从数据库端口/从数据库名称 spring.datasource.slave.username=从数据库用户名 spring.datasource.slave.password=从数据库密码 ``` 3. 创建数据源和数据库连接池:通过@Configuration配置类,使用@Bean注解创建两个数据源和连接池的实例,分别代表主从数据库。例如: ``` @Configuration public class DataSourceConfig { // 主数据源 @Bean(name = "masterDataSource") @ConfigurationProperties(prefix = "spring.datasource") public DataSource masterDataSource() { return DataSourceBuilder.create().build(); } // 从数据源 @Bean(name = "slaveDataSource") @ConfigurationProperties(prefix = "spring.datasource.slave") public DataSource slaveDataSource() { return DataSourceBuilder.create().build(); } } ``` 4. 创建主从数据库的EntityManagerFactory:通过@Configuration配置类,使用@Primary和@Qualifier注解指定主从数据库分别对应的EntityManagerFactory。例如: ``` @Configuration @EnableJpaRepositories( basePackages = "com.example.repositories", entityManagerFactoryRef = "masterEntityManagerFactory", transactionManagerRef = "masterTransactionManager" ) public class MasterConfig { @Autowired @Qualifier("masterDataSource") private DataSource masterDataSource; @Primary @Bean(name = "masterEntityManagerFactory") public LocalContainerEntityManagerFactoryBean masterEntityManagerFactory(EntityManagerFactoryBuilder builder) { return builder .dataSource(masterDataSource) .packages("com.example.models") .build(); } @Primary @Bean(name = "masterTransactionManager") public PlatformTransactionManager masterTransactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(masterEntityManagerFactory(builder).getObject()); } } @Configuration @EnableJpaRepositories( basePackages = "com.example.repositories", entityManagerFactoryRef = "slaveEntityManagerFactory", transactionManagerRef = "slaveTransactionManager" ) public class SlaveConfig { @Autowired @Qualifier("slaveDataSource") private DataSource slaveDataSource; @Bean(name = "slaveEntityManagerFactory") public LocalContainerEntityManagerFactoryBean slaveEntityManagerFactory(EntityManagerFactoryBuilder builder) { return builder .dataSource(slaveDataSource) .packages("com.example.models") .build(); } @Bean(name = "slaveTransactionManager") public PlatformTransactionManager slaveTransactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(slaveEntityManagerFactory(builder).getObject()); } } ``` 5. 在需要取数据的地方进行选择:通过在JpaRepository接口上使用@Qualifier注解,指定使用主数据源还是从数据源。例如: ``` @Repository @Qualifier("masterEntityManagerFactory") public interface UserRepository extends JpaRepository<User, Long> { // ... } ``` 通过以上步骤,就可以在Spring Boot中实现MySQL分离,从而实现数据库的负载均衡和高可用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值