springboot mybatis调用多个数据源引发的错误问题

针对“springboot mybatis调用多个数据源引发的错误问题”,我可以提供如下的攻略过程:

问题背景

在使用SpringBoot和Mybatis框架进行数据源操作时,可能会遇到需要多个数据源的情况,比如:读取或写入的数据源不同,或者需要连接不同的数据库等情况。在这种情况下,我们需要自定义DataSource,同时配置多个SqlSessionFactory和TransactionManager,并且需要在Mapper类上指定使用的数据源名称。但是很多开发者在操作时可能会遇到相关的错误问题,这也是我们本次攻略的重点。

解决方案

1. 自定义多数据源

自定义多数据源需要做如下几点准备:

  1. 定义多个DataSource,可以通过@Configuration和@Bean的方式注入;
  2. 分别配置多个SqlSessionFactory,并且指定使用的DataSource;
  3. 分别配置多个TransactionManager,并且指定使用的DataSource;
  4. 使用MapperScannerConfigurer扫描指定包下的Mapper类,并指定使用的SqlSessionFactory;
  5. 在Mapper类上使用@Qualifier注解指定使用的DataSource名称。

示例代码如下:

@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DataSource1Config {

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

    @Primary
    @Bean(name = "test1SqlSessionFactory")
    public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource test1DataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(test1DataSource);
        return bean.getObject();
    }

    @Primary
    @Bean(name = "test1TransactionManager")
    public DataSourceTransactionManager test1TransactionManager(@Qualifier("test1DataSource") DataSource test1DataSource) {
        return new DataSourceTransactionManager(test1DataSource);
    }

    @Primary
    @Bean(name = "test1SqlSessionTemplate")
    public SqlSessionTemplate test1SqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory test1SqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(test1SqlSessionFactory);
    }
}
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DataSource2Config {

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

    @Bean(name = "test2SqlSessionFactory")
    public SqlSessionFactory test2SqlSessionFactory(@Qualifier("test2DataSource") DataSource test2DataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(test2DataSource);
        return bean.getObject();
    }

    @Bean(name = "test2TransactionManager")
    public DataSourceTransactionManager test2TransactionManager(@Qualifier("test2DataSource") DataSource test2DataSource) {
        return new DataSourceTransactionManager(test2DataSource);
    }

    @Bean(name = "test2SqlSessionTemplate")
    public SqlSessionTemplate test2SqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory test2SqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(test2SqlSessionFactory);
    }
}

2. 指定Mapper使用的数据源

为了解决调用多个数据源引发的错误问题,我们需要在Mapper类上明确指定使用的数据源,这可以通过在Mapper类上添加@Qualifier注解实现,如下所示:

public interface TestMapper {
    @Qualifier("test1DataSource")
    @Select("SELECT * FROM test1 WHERE id = #{id}")
    Test1 getTest1ById(@Param("id") Integer id);

    @Qualifier("test2DataSource")
    @Select("SELECT * FROM test2 WHERE id = #{id}")
    Test2 getTest2ById(@Param("id") Integer id);
}

这样,每个方法都可以明确使用哪个数据源,Mybatis也可以正确地根据指定的DataSource进行数据源切换,避免错误的引用。

示例

我们假设我们需要创建两个数据库test1和test2,每个数据库中都有一个表,分别是test1和test2。下面我们就演示如何通过上述的自定义多数据源和指定Mapper使用的数据源方案,来实现多数据源的操作。

1. 环境搭建

  • 创建两个数据库test1和test2,分别创建test1数据源和test2数据源,并在两个数据源中分别插入一些测试数据。
  • 在Maven工程中添加如下依赖:
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

2. 创建实体类和Mapper类

为了演示需要,我们需要在test1和test2中,各创建一个实体类和Mapper类。

test1实体类:

@Data
public class Test1 {
    private Integer id;
    private String name;
}

test1 Mapper类:

public interface Test1Mapper {
    @Select("SELECT * FROM test1 WHERE id = #{id}")
    Test1 getTest1ById(@Param("id") Integer id);
}

test2实体类:

@Data
public class Test2 {
    private Integer id;
    private String name;
}

test2 Mapper类:

public interface Test2Mapper {
    @Select("SELECT * FROM test2 WHERE id = #{id}")
    Test2 getTest2ById(@Param("id") Integer id);
}

3. 创建Controller类

我们创建一个TestController类,提供如下接口:

  • /test1/{id}:获取test1中指定id的数据;
  • /test2/{id}:获取test2中指定id的数据。
@RestController
public class TestController {

    @Autowired
    private Test1Mapper test1Mapper;
    @Autowired
    private Test2Mapper test2Mapper;

    @GetMapping("/test1/{id}")
    public Test1 getTest1ById(@PathVariable Integer id) {
        return test1Mapper.getTest1ById(id);
    }

    @GetMapping("/test2/{id}")
    public Test2 getTest2ById(@PathVariable Integer id) {
        return test2Mapper.getTest2ById(id);
    }
}

4. 配置多数据源

在我们的application.properties文件中添加如下配置:

# DataSource1
spring.datasource.test1.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.test1.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test1.username=root
spring.datasource.test1.password=root
spring.datasource.test1.initialSize=10
spring.datasource.test1.minIdle=5
spring.datasource.test1.maxActive=50
spring.datasource.test1.validationQuery=SELECT 1 FROM DUAL
spring.datasource.test1.testWhileIdle=true
spring.datasource.test1.testOnBorrow=false
spring.datasource.test1.testOnReturn=false
spring.datasource.test1.poolPreparedStatements=true
spring.datasource.test1.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.test1.filters=wall,stat

# DataSource2
spring.datasource.test2.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.test2.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test2.username=root
spring.datasource.test2.password=root
spring.datasource.test2.initialSize=10
spring.datasource.test2.minIdle=5
spring.datasource.test2.maxActive=50
spring.datasource.test2.validationQuery=SELECT 1 FROM DUAL
spring.datasource.test2.testWhileIdle=true
spring.datasource.test2.testOnBorrow=false
spring.datasource.test2.testOnReturn=false
spring.datasource.test2.poolPreparedStatements=true
spring.datasource.test2.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.test2.filters=wall,stat

5. 启动运行

现在,我们可以直接运行应用程序,并使用如下地址进行访问:

  • http://localhost:8080/test1/1
  • http://localhost:8080/test2/1

分别对test1和test2进行获取数据操作,验证我们的多数据源操作是否生效。

总结

以上就是相关攻略的详细讲解,需要特别注意的是,在实际应用中,可能还需要配置多个数据库连接池,并且需要考虑到安全性、性能等因素,需要根据实际情况进行调整。同时也需要指出的是,Mybatis-plus等工具类在多数据源环境下的使用会更加简单方便,可以考虑使用相应的工具类来进行操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot mybatis调用多个数据源引发的错误问题 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • Oracle 查询死锁并解锁的终极处理方法

    Oracle 查询死锁并解锁的终极处理方法 死锁是数据库中常见的问题之一,它会导致应用程序被挂起、性能下降,从而影响整个系统的可用性。本文将介绍Oracle查询死锁并解锁的终极处理方法,包括以下步骤: 检测死锁 Oracle提供了一些技术来检查是否存在死锁: 查询v$session视图 sqlSELECT s.sid, s.serial#, l.*, dec…

    database 2023年5月21日
    00
  • 如何单机部署多个 MySQL 8.0 实例 ?

    在服务器资源有限的情况下,可利用该方案快速搭建各类 mysql 架构方案。各 MySQL 实例共享一个 mysqld 主程序,但各实例数据目录是独立的,存放在不同的文件夹中;好了、废话不多说,直接上干货,具体搭建步骤如下 环境介绍 实例 主机 mysql port mysqlx port datadir mysql1 192.168.31.100 3306 …

    MySQL 2023年4月8日
    00
  • cmd中MySQL中文数据乱码问题解决方法

    下面是详细讲解“cmd中MySQL中文数据乱码问题解决方法”的完整攻略。 问题背景 在使用cmd命令行窗口操作MySQL数据库时,有时会遇到中文数据乱码问题,这主要是由于cmd默认使用的编码格式为gbk,而MySQL默认使用的编码格式为utf8,两者不兼容所导致的。 解决方法 (以下操作均在cmd命令行窗口中进行) 1. 修改MySQL客户端默认编码格式为g…

    database 2023年5月18日
    00
  • asp在线执行sql语句的函数

    下面我将为您详细讲解“asp在线执行sql语句的函数”的完整攻略。 什么是“asp在线执行sql语句的函数”? “asp在线执行sql语句的函数”是指在ASP网页中使用VBScript编写的函数,用于在网页中连接到数据库并执行SQL语句,获取或修改数据库的内容。这个函数可以方便我们进行网页开发,提高网站的运行效率。 函数的基本语法 下面是“asp在线执行sq…

    database 2023年5月21日
    00
  • C# SQLite执行效率的优化教程

    C# SQLite执行效率的优化主要从以下几个方面入手: 1. 数据库设计优化 在数据库设计时,应遵循以下原则进行优化: 1.1 表字段设计 表字段设计时,应尽量避免使用BLOB(二进制类型)和TEXT类型,这类字段需要频繁的I/O操作和内存申请,对性能会造成不小的影响。如果确实需要使用这类字段,可以通过异步读写或者考虑分表进行优化。 1.2 索引优化 索引…

    database 2023年5月19日
    00
  • 在命令行下进行Oracle用户解锁的语句

    Sure,下面是在命令行下进行Oracle用户解锁的完整攻略: 步骤一:登录SQL Plus 在命令行界面下,通过以下命令登录SQL Plus: sqlplus / as sysdba 这里 / as sysdba 表示使用具有 SYSDBA 角色的特权用户连接到 Oracle 数据库。 步骤二:确认用户被锁 在 SQL Plus 下输入以下命令,确认要解锁…

    database 2023年5月21日
    00
  • Php中使用Select 查询语句的实例

    下面是关于在PHP中使用Select查询语句的攻略: 1. 准备工作 在使用Select查询语句前,需要进行以下准备工作: 1.1 连接数据库 在PHP中连接数据库需要使用mysqli扩展或PDO扩展,这里以mysqli扩展为例,代码如下: // 创建连接 $conn = new mysqli($servername, $username, $passwor…

    database 2023年5月21日
    00
  • 一文搞懂SQL注入攻击

    一文搞懂SQL注入攻击 什么是SQL注入攻击? SQL(Structured Query Language)是用于管理关系数据库管理系统的语言。SQL注入攻击是指黑客通过构造恶意的SQL语句,使得应用程序在对用户输入数据的处理过程中,将不可信的数据作为SQL查询语言的一部分,从而使应用程序的数据库受到攻击的一种攻击方法。 攻击者在不需要任何身份验证的情况下即…

    database 2023年5月21日
    00
合作推广
合作推广
分享本页
返回顶部