千家信息网

在SpringBoot应用程序中使用多个数据源的示例分析

发表于:2024-12-12 作者:千家信息网编辑
千家信息网最后更新 2024年12月12日,小编给大家分享一下在SpringBoot应用程序中使用多个数据源的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!属
千家信息网最后更新 2024年12月12日在SpringBoot应用程序中使用多个数据源的示例分析

小编给大家分享一下在SpringBoot应用程序中使用多个数据源的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

属性文件

首先,让我们在 application.properties 文件中定义两个不同的数据源设置,如下所示:

server.port=9090spring.output.ansi.enabled=ALWAYSapplication-description=@project.description@application-version=@project.version@spring.customerdatasource.url=[url1]spring.customerdatasource.username=[username1]spring.customerdatasource.password=[password1]spring.customerdatasource.driverClassName=oracle.jdbc.OracleDriverspring.billingdatasource.url=[url2]spring.billingdatasource.username=[username2]spring.billingdatasource.password=[password1]spring.billingdatasource.driverClassName=oracle.jdbc.OracleDriverdatabase.sql.databasename=SELECT dbid, name FROM v$database

正如我之前提到的,我使用过 Oracle 数据库,但你也可以使用其他数据库,只要相应地更改 driverClassName

数据源配置

为了创建 DataSource bean,我创建了一个 DatasourceConfig 类并将其注释为配置,并将两个数据源添加为两个不同的 bean

import javax.sql.DataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import org.springframework.jdbc.datasource.DriverManagerDataSource;@Configurationpublic class DatasourceConfig {        Environment env;                public DatasourceConfig(Environment env) {                this.env = env;        }        @Bean(name = "customerDataSource")    public DataSource customerDataSource() {            DriverManagerDataSource dataSource = new DriverManagerDataSource();        dataSource.setDriverClassName(env.getProperty("spring.customerdatasource.driverClassName"));        dataSource.setUrl(env.getProperty("spring.customerdatasource.url"));        dataSource.setUsername(env.getProperty("spring.customerdatasource.username"));        dataSource.setPassword(env.getProperty("spring.customerdatasource.password"));        return dataSource;    }    @Bean(name = "billingDataSource")    public DataSource billingDataSource() {            DriverManagerDataSource dataSource = new DriverManagerDataSource();        dataSource.setDriverClassName(env.getProperty("spring.billingdatasource.driverClassName"));        dataSource.setUrl(env.getProperty("spring.billingdatasource.url"));        dataSource.setUsername(env.getProperty("spring.billingdatasource.username"));        dataSource.setPassword(env.getProperty("spring.billingdatasource.password"));        return dataSource;    }    }

数据访问

我使用了 JdbcTemplate作为数据访问。要创建 DAO 接口,请在 com.tech.multipledatasources.dao 包下添加 IDatabaseDAO 接口,如下所示:

import com.tech.multipledatasources.domain.DatabaseInfo;public interface IDatabaseDAO {        public DatabaseInfo getDatabaseInfo();}

我对这个接口做了两种不同的实现,因为即使它是一个简单的应用程序,现实生活中的场景也会有所不同。

import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;import com.tech.multipledatasources.domain.DatabaseInfo;@Repositorypublic class BillingDAO implements IDatabaseDAO{        private JdbcTemplate jdbcTemplate;        @Value("${database.sql.databasename}")    private String sql;    public BillingDAO(@Qualifier("billingDataSource")DataSource datasource) {        jdbcTemplate = new JdbcTemplate(datasource);    }    @Override    public DatabaseInfo getDatabaseInfo() {        return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(DatabaseInfo.class));    }}
import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;import com.tech.multipledatasources.domain.DatabaseInfo;@Repositorypublic class CustomerDAO implements IDatabaseDAO {    private JdbcTemplate jdbcTemplate;        @Value("${database.sql.databasename}")    private String sql;    public CustomerDAO(@Qualifier("customerDataSource") DataSource datasource) {        jdbcTemplate = new JdbcTemplate(datasource);    }    @Override    public DatabaseInfo getDatabaseInfo() {        return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(DatabaseInfo.class));    }}

对于 database.sql.databasename 变量,请在 application.properties 文件中添加"SELECT dbid, name FROM v$database"值。请注意,此 SQL 也适用于 Oracle 数据库。如果您打算使用不同的数据库,则需要更改此语句。

我使用构造函数级别的依赖注入来注入数据源,并使用 Qualifier 注释来指定 bean 名称。

我还使用 DatabaseInfo 模型类将 SQL 结果映射到一个对象中。

import lombok.AllArgsConstructor;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import lombok.ToString;@Getter@Setter@AllArgsConstructor@NoArgsConstructor@ToStringpublic class DatabaseInfo {    private long dbid;    private String name;    }

为了保持代码干净整洁,我使用了Lombok插件。

服务

我添加了两个服务类作为服务层,如下所示,注释为服务,并注入相关的DAO类:

import com.tech.multipledatasources.dao.BillingDAO;import com.tech.multipledatasources.domain.DatabaseInfo;import org.springframework.stereotype.Service;@Servicepublic class BillingService {        private BillingDAO billingDAO;    public BillingService(BillingDAO billingDAO){        this.billingDAO = billingDAO;    }    public DatabaseInfo getDatabaseInfo(){        return billingDAO.getDatabaseInfo();    }}
import com.tech.multipledatasources.dao.CustomerDAO;import com.tech.multipledatasources.domain.DatabaseInfo;import org.springframework.stereotype.Service;@Servicepublic class CustomerService {        private CustomerDAO customerDAO;    public CustomerService(CustomerDAO customerDAO){        this.customerDAO = customerDAO;    }    public DatabaseInfo getDatabaseInfo(){        return customerDAO.getDatabaseInfo();    }}

异常处理

我在下面创建了 CustomException 类,并在 ControllerAdvice 中使用了中央异常处理:

import lombok.AllArgsConstructor;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import lombok.ToString;import java.util.Date;@Getter@Setter@AllArgsConstructor@NoArgsConstructor@ToStringpublic class CustomException extends Exception {        private static final long serialVersionUID = 1L;        private int errStatusCode;    private String errMsg;    private Date errDate;    private String reqDesc; }
import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.context.request.WebRequest;import java.util.Date;public class ControllerExceptionHandler {        @ExceptionHandler(Exception.class)    public ResponseEntity genericExceptionHandler(Exception ex, WebRequest request) {        CustomException customException = new CustomException(            HttpStatus.EXPECTATION_FAILED.value(),            ex.getMessage(),            new Date(),            request.getDescription(false)            );                return new ResponseEntity(customException, HttpStatus.EXPECTATION_FAILED);      }}

控制器

我创建了两个控制器。一种用于计费,一种用于客户请求;将两个服务类注入控制器。

import com.tech.multipledatasources.domain.DatabaseInfo;import com.tech.multipledatasources.service.BillingService;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/billing")public class BillingController {        private BillingService billingService;    public BillingController(BillingService billingService){        this.billingService = billingService;    }    @GetMapping("/dsinfo")    public ResponseEntity getDatasourceInfo(){        return ResponseEntity.ok(billingService.getDatabaseInfo());    }}
import com.tech.multipledatasources.domain.DatabaseInfo;import com.tech.multipledatasources.service.CustomerService;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/customer")public class CustomerController {        private CustomerService customerService;    public CustomerController(CustomerService customerService){        this.customerService = customerService;    }        @GetMapping("/dsinfo")    public ResponseEntity getDatasourceInfo(){        return ResponseEntity.ok(customerService.getDatabaseInfo());    }}

运行应用程序

运行应用程序请求后,它将返回结果,该结果将指示我们刚刚在连接中创建的数据库。

以上是"在SpringBoot应用程序中使用多个数据源的示例分析"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0