当前位置: 首页 > 知识库问答 >
问题:

在一个服务类中使用jdbcTemplates访问多个数据源

宗政卓
2023-03-14

下面是我的情况:我有两个数据库:一个sybase和一个MSSQL。我希望在一个服务类中访问这两个数据库。例如,我想从sybase获得一些数据,然后我需要在MSSQL上做一些更新。

我已经根据网上找到的多个样本设置了两个数据源,但我无法访问我的第二个数据库(sybase)。

下面是我的代码:

spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp


# Database
# spring.datasource.jndi-name=jdbc/database1
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.datasource.url=jdbc:jtds:sqlserver://database1/db_aes
spring.datasource.username=user1
spring.datasource.password=password1

# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1

# 2nd Database
spring.secondDatasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.secondDatasource.url=jdbc:jtds:sybase://database2/aidcconfig
spring.secondDatasource.username=user2
spring.secondDatasource.password=password2
spring.secondDatasource.hibernate.dialect = org.hibernate.dialect.SybaseASE15Dialect
spring.secondDatasource.testWhileIdle = true
spring.secondDatasource.validationQuery = SELECT 1


# Show or not log for each sql query
spring.jpa.show-sql = false

# Hibernate ddl auto (create, create-drop, update, validate)
spring.jpa.hibernate.ddl-auto = validate

# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.EJB3NamingStrategy

# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SQLServerDialect

com.ibm.websphere.persistence.ApplicationsExcludedFromJpaProcessing=*
@Component("fileUploadService")
@Transactional
public class FileUploadServiceImpl implements FileUploadService {

    @Autowired
    @Qualifier("dbAesJdbcTemplate")
    JdbcTemplate dbAesJdbcTemplate;

    @Autowired
    @Qualifier("aidcconfigJdbcTemplate")
    JdbcTemplate aidcconfigJdbcTemplate;

    private int uploadId = 1;

    private void testDB(){
            String db = aidcconfigJdbcTemplate.queryForObject("select db_name()", String.class);
            System.out.println("database name: " + db);
    }
...
}
package config.database;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "dbAesEntityManagerFactory",
        transactionManagerRef = "dbAesTransactionManager",
        basePackages = {"web.fileUpload.repo.db_aes.dao"}
        )
public class DbAesDataSource {

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

    @Bean(name="dbAesJdbcTemplate")
    public JdbcTemplate dbAesJdbcTemplate(@Qualifier("dbAesDataSource") DataSource dbAesDataSource)
    {
        return new JdbcTemplate(dbAesDataSource);
    }

    @Bean(name="dbAesEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean dbAesEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("dbAesDataSource") DataSource dbAesDataSource) {
        return builder
                .dataSource(dbAesDataSource)
                .packages("web.fileUpload.repo.db_aes.models")
                .build();
    }

    @Bean(name = "dbAesTransactionManager")
    public PlatformTransactionManager dbAesTransactionManager(
            @Qualifier("dbAesEntityManagerFactory") EntityManagerFactory dbAesEntityManagerFactory) {
        return new JpaTransactionManager(dbAesEntityManagerFactory);
    }
}

AIDCConfigDataSource

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "aidcconfigEntityManagerFactory",
        transactionManagerRef = "aidcconfigTransactionManager",
        basePackages = {"web.fileUpload.repo.aidcconfig.dao"}
        )
public class AidcconfigDataSource {

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

    @Bean(name="aidcconfigJdbcTemplate")
    public JdbcTemplate aidcconfigJdbcTemplate(@Qualifier("aidcconfigDataSource") DataSource aidcconfigDataSource)
    {
        return new JdbcTemplate(aidcconfigDataSource);
    }

    @Bean(name="aidcconfigEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean aidcconfigEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("aidcconfigDataSource") DataSource aidcconfigDataSource) {
        return builder
                .dataSource(aidcconfigDataSource)
                .packages("web.fileUpload.repo.aidcconfig.models")
                .build();
    }

    @Bean(name = "aidcconfigTransactionManager")
    public PlatformTransactionManager aidcconfigTransactionManager(
            @Qualifier("aidcconfigEntityManagerFactory") EntityManagerFactory aidcconfigEntityManagerFactory) {
        return new JpaTransactionManager(aidcconfigEntityManagerFactory);
    }
}

以下是我的错误:

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.5.RELEASE:run (default-cli) on
 project testUpload: An exception occurred while running. null: InvocationTargetException: Error creating bean with
 name 'fileDownloadController': Injection of autowired dependencies failed; nested exception is org.springframework
.beans.factory.BeanCreationException: Could not autowire field: private web.fileUpload.services.FileUploadService w
eb.fileUpload.controller.FileDownloadController.fileUploadService; nested exception is org.springframework.beans.fa
ctory.BeanCreationException: Error creating bean with name 'fileUploadService': Injection of autowired dependencies
 failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org
.springframework.jdbc.core.JdbcTemplate web.fileUpload.services.FileUploadServiceImpl.dbAesJdbcTemplate; nested exc
eption is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springfr
amework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidat
e for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=tr
ue), @org.springframework.beans.factory.annotation.Qualifier(value=dbAesJdbcTemplate)} -> [Help 1]

如果我删除了FileUploadServiceImpl中的限定符,那么任何jdbcTemplate都将只连接到我的主数据库db_aes。如何使用JDBCTemplate访问第二个数据源?

Spring Boot中的多数据源和JdbcTemplate(>1.1.0)

尝试#1我注意到它无法创建bean,我在AidcconfigDataSource类中放置了一些记录器。结果,我没有看到我的方法正在执行。因此,我假设应用程序没有读取我的AidcconfigDataSource类。

我将config文件夹从java/config重新定位到java/web/config:

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.5.RELEASE:run (default-cli) on
 project testUpload: An exception occurred while running. null: InvocationTargetException: Error creating bean with
 name 'dataSourceInitializerPostProcessor': Injection of autowired dependencies failed; nested exception is org.spr
ingframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.beans.facto
ry.BeanFactory org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.beanFactory; nested e
xception is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'aidc
configDataSource' defined in class path resource [web/config/database/AidcconfigDataSource.class]: factory-bean ref
erence points back to the same bean definition -> [Help 1]

我已经将bean的名称从aidcconfigDataSource更改为aidcconfigDS,并将其改为主数据源。另外,我在application.properties中添加了“spring.jpa.open_in_view=false”。然而,另一个错误发生了。如何正确地做到这一点?

2016-11-03 09:28:16.118 ERROR 11412 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.servic
e() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exce
ption is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springf
ramework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: dbAesTransa
ctionManager,aidcconfigTransactionManager] with root cause

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.
transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: dbAesTransactionMana
ger,aidcconfigTransactionManager

共有1个答案

窦伟
2023-03-14

我认为Spring Boot试图实例化两个具有相同名称的bean:AIDCConfigDataSource

一个是您的配置类AIDCConfigDataSource.class,另一个是bean

@Bean(name="aidcconfigDataSource")
    @ConfigurationProperties(prefix = "spring.secondDatasource")
    public DataSource aidcconfigDataSource(){
        return DataSourceBuilder.create().build();
    }
 类似资料:
  • 我们的应用程序是一个中间层应用程序,它提供了十几个左右的前端应用程序,可以访问后端的几十个数据库(和其他数据源)。 我们决定使用OSGi将不相关的代码位分离到单独的包中。这确保了正确的代码封装,甚至允许特定捆绑包的热交换。 这样做的一个优点是,与特定数据库对话的任何代码都被隔离到单个捆绑包中。它还允许我们简单地为新的目的地插入新的捆绑包,并无缝地集成新代码。它还确保了如果单个后端数据源关闭,对其他

  • 尝试从同一命名空间中的另一个服务连接到一个服务。使用ClusterIP创建服务。创建服务后使用该Ip访问服务。请求有时成功,有时失败,我看到两个pod都启动并运行。以下是服务配置

  • 问题内容: 我正在运行一台正在监听的服务器,公开了2个服务:和。由于这两项服务都可以从访问,因此我只想从存根拨打该地址。 服务器看起来像这样: 为什么每种服务都需要拨不同的插座? 而且由于代码基本上是重复的,以适应每种服务,所以我不能只使用an 来减少代码吗? 然后使用它为每个服务实现客户端功能,而不是为每个服务创建新功能。我已经找到了cmux,但是必须有一种无需使用外部库即可执行此操作的方法。

  • 我正在尝试使用单个Service yaml在多个节点上设置对Pods的访问。Pods都有相同的标签(例如),但分布在多个节点上,而不是在单个节点上。 据我所知,我可以设置一个服务,通过节点端口转发对Pod的访问,比如: 其中访问节点上的端口30000会转发到pod上的端口5000。 如果我在多个节点上有pod,有没有一种方法可以让客户端访问一个endpoint,例如服务本身,从而在循环中获得任何p

  • 与此处的问题类似,仅通过管理员授权访问Office 365用户邮件数据 目前,我正在实现一个应用程序,它将使用服务号访问Office e365上的一组邮箱。 有一篇MSDN博客文章宣布oauth支持Office 365http://blogs.msdn.com/b/exchangedev/archive/2014/03/25/using-oauth2-to-access-calendar-cont

  • null 根据AWS文档,您应该始终为EC2创建角色,并根据您的需求为角色分配策略。 向一个角色授予多个服务访问权限是否存在安全问题?我问这个问题的原因是,使用EC2元数据,您可以在此时使用该角色获得分配给EC2实例的accesskey信息。EC2经常刷新密钥。 任何反馈或输入。