spring boot 连接多个数据库 [英] Connecting to multiple database in spring boot
问题描述
我需要连接到我的项目中的两个数据库.所以我创建了两个配置文件.
I need to connect to two database in my project. So I created two configuration files.
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories( basePackages = {"com.virat.webservices.datastore.v1.Repo" } )
@EntityScan("com.virat.webservices.datastore.v1.Model")
public class V1DBConfig {
@Primary
@Bean( name = "dataSource" )
@ConfigurationProperties( prefix = "v1.datasource" )
public DataSource dataSource()
{
return DataSourceBuilder.create().build();
}
@Primary
@Bean( name = "entityManagerFactory" )
public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder,
@Qualifier( "dataSource" ) DataSource dataSource )
{
return builder.dataSource(dataSource).packages("com.virat.webservices.datastore.v1.Model")
.persistenceUnit("db1").build();
}
@Primary
@Bean( name = "transactionManager" )
public PlatformTransactionManager transactionManager(
@Qualifier( "entityManagerFactory" ) EntityManagerFactory entityManagerFactory )
{
return new JpaTransactionManager(entityManagerFactory);
}
}
和
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories( entityManagerFactoryRef = "v2EntityManagerFactory", transactionManagerRef = "v2TransactionManager", basePackages = {
"com.virat.datastore.repository" } )
@EntityScan( "com.virat.datastore.model" )
public class V2DBConfig {
@Bean( name = "v2DataSource" )
@ConfigurationProperties( prefix = "spring.datasource" )
public DataSource dataSource()
{
return DataSourceBuilder.create().build();
}
@Bean( name = "v2EntityManagerFactory" )
public LocalContainerEntityManagerFactoryBean barEntityManagerFactory( EntityManagerFactoryBuilder builder,
@Qualifier( "v2DataSource" ) DataSource dataSource )
{
return builder.dataSource(dataSource).packages("com.virat.model")
.persistenceUnit("db2").build();
}
@Bean( name = "v2TransactionManager" )
public PlatformTransactionManager barTransactionManager(
@Qualifier( "v2EntityManagerFactory" ) EntityManagerFactory barEntityManagerFactory )
{
return new JpaTransactionManager(barEntityManagerFactory);
}
}
我将我的 application.properties
文件配置为,
And I configured my application.properties
file as,
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db2? useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=fal. se&serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=
#spring.datasource.pool.size=20
v1.datasource.driver-class-name=com.mysql.jdbc.Driver
v1.datasource.url=jdbc:mysql://localhost:3306/db1? useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=fal. se&serverTimezone=UTC&useSSL=false
v1.datasource.username=root
v1.datasource.password=
#v1.datasource.pool.size=20
spring.jpa.properties.hibernate.id.new_generator_mappings=false
v1.jpa.properties.hibernate.id.new_generator_mappings=false
#spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
但是当我运行应用程序时,抛出了以下异常.
But when I run the application, the following exception has been thrown.
***************************
APPLICATION FAILED TO START
***************************
Description:
Field entityManager in com.highpeak.tlp.webservices.services.impl.TaskServiceImpl required a single bean, but 2 were found:
- org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
- org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter:42 -
***************************
APPLICATION FAILED TO START
***************************
Description:
Field entityManager in com.highpeak.tlp.webservices.services.impl.TaskServiceImpl required a single bean, but 2 were found:
- org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
- org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
Disconnected from the target VM, address: '127.0.0.1:56875', transport: 'socket'
Process finished with exit code 1
我无法确定错误是什么.我有两个模块.一个数据库的repository
和entity
类在一个模块中,而另一个数据库的类在另一个模块中.这会导致问题吗?
I am unable to identify what is the error. I have two modules. The repository
and entity
class of one database is in one module and the other database's classes in another module. Is this causing issue?
编辑
我的TaskServiceImpl.java
package com.virat.webservices.services.impl;
@Service
public class TaskServiceImpl implements TaskService {
private static final Logger LOGGER = LoggerFactory.getLogger(TaskServiceImpl.class);
@Autowired
@PersistenceContext(unitName = "v2EntityManagerFactory")
private EntityManager entityManager;
@Value( "${file.base.path}" )
private String basePath;
@Value( "${application.domain}" )
private String applicationDomain;
@Value( "${application.protocol}" )
private String applicationProtocol;
@Value( "${server.port}" )
private String serverPort;
@Override
@SuppressWarnings( "unchecked" )
@Transactional( rollbackOn = DataException.class )
public Integer doSomething( SomeObject someObject,
UserAccessDetails userAccessDetails ) throws DataException
{
try
{
// Do input validations
if( NullEmptyUtils.isNull(userAccessDetails) || NullEmptyUtils.isNull(someObject) )
{
throw new DataException(GeneralConstants.EXCEPTION, GeneralConstants.NULL_INPUT_ERROR,
HttpStatus.BAD_REQUEST);
}
// Creates a native mysql query based on the contents of lawyerDiscoveryParamsBean
/* Should be replaced with criteria API */
String generatedQuery = DynamicQueryGenerator.getDynamicQuery(someObject, owner);
LOGGER.info("Generated query: {}", generatedQuery);
Query executableQuery = entityManager.createNativeQuery(generatedQuery, UserModel.class);
List<UserModel> userModels = executableQuery.getResultList();
if( userModels.isEmpty() )
{
return 0;
}
return 1;
}
catch( DataException e )
{
LOGGER.error(GeneralConstants.ERROR, e);
throw e;
}
catch( Exception e )
{
LOGGER.error(GeneralConstants.ERROR, e);
throw new DataException(GeneralConstants.EXCEPTION, GeneralConstants.SOMETHING_WENT_WRONG,
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
推荐答案
在V1DBConfig.java
中,注解@EnableJpaRepository
其实应该是这样的,
In V1DBConfig.java
, the annotation @EnableJpaRepository
should actually be like this,
@EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager", basePackages = {
"com.virat.webservices.datastore.v1.Repo" } )
您已经在V2DBConfig.java
类中进行了正确的配置(查看@EnableJpaRepository
注释).在 V1DBConfig.java
中做同样的事情.
You have done the configuration right in the class V2DBConfig.java
(Look at the @EnableJpaRepository
annotation). Do the same thing in V1DBConfig.java
.
然后,在您的 TaskServiceImpl.java
中,提供 PersistenceContext
,正如 @丹.我希望这会有所帮助.
And then, in your TaskServiceImpl.java
, provide PersistenceContext
, as answered by @Dan. I hope this helps.
这篇关于spring boot 连接多个数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!