Spring Boot配置雙數據源

一、Spring Boot配置雙數據源報錯

在實際應用中,經常會遇到需要配置多個數據源的情況。在Spring Boot中,配置多個數據源的方式不同於傳統的Spring MVC,因此很容易出現配置錯誤的情況。下面介紹一些出錯原因和解決方法。

1、錯誤原因:沒有指定主數據源

@Configuration
@MapperScan(basePackages = "com.example.mapper1", sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DataSource1Config {
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource1")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public SqlSessionFactory sqlSessionFactory1() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource1());
        return bean.getObject();
    }

    @Bean
    @Primary
    public SqlSessionTemplate sqlSessionTemplate1() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory1());
    }
}

@Configuration
@MapperScan(basePackages = "com.example.mapper2", sqlSessionTemplateRef = "sqlSessionTemplate2")
public class DataSource2Config {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource2")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory2() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource2());
        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate2() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory2());
    }
}

在這個例子中,我們定義了兩個數據源dataSource1和dataSource2,並指定了相應的SqlSessionFactory和SqlSessionTemplate。在這個過程中,我們使用了Primary註解來指定主數據源。如果沒有指定主數據源,會拋出如下錯誤信息:

No qualifying bean of type 'com.example.mapper1.AppMapper' available: expected at least 1 bean which qualifies as autowire candidate.

2、錯誤原因:沒有指定MapperScan

在配置多數據源時,我們需要指定每個數據源所使用的MapperScan,如下所示:

@Configuration
@MapperScan(basePackages = "com.example.mapper1", sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DataSource1Config {
    ...
}

如果沒有指定MapperScan,會提示找不到該Mapper的信息。因此,我們需要注意這一點。

二、Spring Boot配置JNDI數據源

除了使用配置文件配置數據源之外,我們還可以使用JNDI數據源,在Spring Boot中,使用JNDI數據源的方式與傳統的Spring MVC相同。下面是一個使用JNDI數據源的例子:

@Configuration
public class JndiDataSourceConfig {
    @Bean(destroyMethod="")
    public DataSource dataSource() throws Exception {
        Context ctx = new InitialContext();
        return (DataSource) ctx.lookup("java:comp/env/jdbc/myAppDataSource");
    }
}

三、Spring Boot配置雙數據源查詢報錯

在使用雙數據源查詢時,需要注意事項:

1、在DAO層中指定數據源

在使用MyBatis進行多數據源操作時,默認情況下會使用主數據源對應的SqlSessionTemplate,因此需要在DAO層中指定所使用的數據源,如下所示:

@Repository
public interface AppMapper {
    @Select("SELECT * FROM app WHERE id = #{id}")
    @DataSource("dataSource2")
    App findById(@Param("id") Long id);
}

2、在配置文件中指定MapperScan

核心代碼如下:

@MapperScan(basePackages = "com.example.mapper1", sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DataSource1Config {
    ...
}

3、在具體查詢語句中指定表名

由於不同的數據源可能訪問了不同的表,因此需要在具體的查詢語句中指定表名,如下所示:

@Select("SELECT * FROM app_2 WHERE id = #{id}")
App findById(@Param("id") Long id);

四、Spring Boot連接池配置

連接池是指程序和數據庫之間的連接插座,每個連接池都是一個單獨的連接對象,與其他連接池之間獨立,相互不影響。在Spring Boot中,常用的連接池有Apache DBCP和HikariCP。

1、使用Apache DBCP連接池

在使用Apache DBCP連接池時,需要添加以下依賴:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>9.0.19</version>
</dependency>

同時,在配置文件中添加以下代碼:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root

# DBCP連接池配置
spring.datasource.tomcat.initial-size=5
spring.datasource.tomcat.max-idle=10
spring.datasource.tomcat.min-idle=5
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.test-on-return=true
spring.datasource.tomcat.validation-query=SELECT 1

2、使用HikariCP連接池

在使用HikariCP連接池時,需要添加以下依賴:

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>3.3.1</version>
</dependency>

同時,在配置文件中添加以下代碼:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root

# HikariCP連接池配置
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=MyHikariCP
spring.datasource.hikari.connection-timeout=20000

五、完整代碼示例

完整的Spring Boot配置雙數據源的代碼示例:

1、數據源配置

@Configuration
@MapperScan(basePackages = "com.example.mapper1", sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DataSource1Config {
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource1")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public SqlSessionFactory sqlSessionFactory1() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource1());
        return bean.getObject();
    }

    @Bean
    @Primary
    public SqlSessionTemplate sqlSessionTemplate1() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory1());
    }
}

@Configuration
@MapperScan(basePackages = "com.example.mapper2", sqlSessionTemplateRef = "sqlSessionTemplate2")
public class DataSource2Config {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource2")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory2() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource2());
        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate2() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory2());
    }
}

2、查詢語句

@Repository
public interface AppMapper {
    @Select("SELECT * FROM app WHERE id = #{id}")
    @DataSource("dataSource2")
    App findById(@Param("id") Long id);
}

3、連接池配置

使用HikariCP連接池的示例代碼如下:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root

# HikariCP連接池配置
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=MyHikariCP
spring.datasource.hikari.connection-timeout=20000

原創文章,作者:GRJUI,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/334530.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
GRJUI的頭像GRJUI
上一篇 2025-02-05 13:05
下一篇 2025-02-05 13:05

相關推薦

發表回復

登錄後才能評論