首页 新闻 会员 周边 捐助

SpringBoot项目整合Druid连接池,如何使用@Mybatis注解测试数据库Mapper?

0
悬赏园豆:20 [已解决问题] 解决于 2024-05-16 21:54

SpringBoot项目,整合druid连接池,pom文件如下

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

配置文件中使用druid 配置连接池:

spring.datasource.druid.url = ${数据库URL}
spring.datasource.druid.username = ${数据库用户名}
spring.datasource.druid.password = ${数据库密码}
spring.datasource.druid.driver = org.postgresql.Driver

同一份配置文件,内容完全一致,分别在 src/main/resource/application.propertiessrc/test/resource/application-test.properties 中定义

测试类代码如下:

@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDataBase.Replace.NONE)
@ActiveProfiles("test")
class DemoMapperTest {
    @Autowired
    private DemoMapper demoMapper;

    @Test
    void testInsert() {
        DemoModel d = new DemoModel();
        d.setName("name");
        d.setNumber(123);
        d.setTime(new Date());
        
        int result = demoMapper.insert(d);
        assertThat(result).isEqualTo(1);
    }
}

运行该测试类,报错

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class.

但是,如果我把 @MybatisTest 换成 @SpringBootTest,则一切正常。
该应用正常启动部署,也一切正常。只有用 @MybatisTest 无法运行测试类。

经过自己排查分析以后我发现就是 druid 连接池的问题,如果去掉 druid 连接池,则 @MybatisTest 注解可以正常工作。

请问一下如何配置项目或者使用什么注解,才能使 @MybatisTest 可以接受 Druid 连接池?

飞鸟_Asuka的主页 飞鸟_Asuka | 菜鸟二级 | 园豆:393
提问于:2024-05-16 17:27
< >
分享
最佳答案
1

问题出在@MybatisTest注解与Druid连接池的兼容性上。@MybatisTest注解会自动配置内存中的嵌入式数据库,而Druid连接池并不支持嵌入式数据库。因此,你需要手动配置测试环境以使用Druid连接池。

你可以创建一个单独的测试配置类,用于配置Druid连接池和MyBatis相关的Bean。这样,在测试期间,Spring Boot就会使用你的Druid配置来连接真实的数据库。

首先,创建一个测试配置类,例如TestConfig:

java
Copy code
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@TestConfiguration
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisAutoConfiguration.class})
public class TestConfig {

@Bean
@Primary
public DataSource dataSource() {
    // 在这里配置Druid连接池
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setUrl("jdbc:postgresql://your-database-url");
    dataSource.setUsername("your-username");
    dataSource.setPassword("your-password");
    return dataSource;
}

}
然后,在测试类中使用@Import注解引入这个测试配置类:

java
Copy code
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Date;

import static org.assertj.core.api.Assertions.assertThat;

@MybatisTest
@Import(TestConfig.class)
@ActiveProfiles("test")
@ExtendWith(SpringExtension.class)
class DemoMapperTest {

@Autowired
private DemoMapper demoMapper;

@Test
void testInsert() {
    DemoModel d = new DemoModel();
    d.setName("name");
    d.setNumber(123);
    d.setTime(new Date());

    int result = demoMapper.insert(d);
    assertThat(result).isEqualTo(1);
}

}
这样配置后,测试类就会使用Druid连接池进行数据库连接,同时使用MyBatis进行数据访问。

收获园豆:20
Technologyforgood | 大侠五级 |园豆:7535 | 2024-05-16 20:41

非常感谢!问题解决了!

飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2024-05-16 21:54
其他回答(1)
0

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
添加这段,我当时是这样解决的,用的是Hirika连接池。不过种类都差不多。

蜗牛旅行1899 | 园豆:285 (菜鸟二级) | 2024-05-16 17:30

用 Hikari 连接池,就是我问题中描述的,如果在配置文件中把 druid 连接池去掉

# spring.datasource.druid.url = ${数据库URL}  <-- 去掉
spring.datasource.url = ${数据库URL}
# username,password,driver同上

这样就可以了

然后你提供的这个方法我试了并不行

支持(0) 反对(0) 飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2024-05-16 17:40

@飞鸟_Asuka: spring.datasource本质是spring boot自动注入连接池,但是它允许你选择,只需要添加连接池的前缀即可。但是所有连接池都有四个属性,driver,password,url,name,
所以c3p0是这样的:
spring:
datasource:
# 基础信息
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
username: test
password: test
type: com.mchange.v2.c3p0.ComboPooledDataSource
c3p0:
# 测试连接
connection-tester-className: com.rain.Tester.ConnectionTesterSample
spring:
datasource:
# 基础信息
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
username: test
password: test
schema: test
hikari:
pool-name: test_hikari
# 测试
connection-test-query : select now() #
看到它们两个其实url,driver-class-name,password,username都是公共的。所以你写的

spring.datasource.druid.url = ${数据库URL} <-- 去掉

spring.datasource.url = ${数据库URL}
这两个本质是一样的。假设以c3p0为例。

spring.datasource.c3p0.url 与 spring.datasource.url都是一样的。

支持(0) 反对(0) 蜗牛旅行1899 | 园豆:285 (菜鸟二级) | 2024-05-17 10:54

@蜗牛旅行1899: 你可以看下上面的答案 通过手动构造数据源的方法可以解决

支持(0) 反对(0) 飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2024-05-17 11:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册