java Spring:如何使用 GenericDao 获取多个数据源?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13345206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring : how to get multiple datasource with GenericDao?
提问by MychaL
i have a web application using Spring 3.1.1. We have a genericDao using JdbcTemplate. Datasource is injecting like this in the GenericDaoImpl.
我有一个使用 Spring 3.1.1 的 Web 应用程序。我们有一个使用 JdbcTemplate 的 genericDao。数据源在 GenericDaoImpl 中是这样注入的。
public class GenericDaoImpl<T extends Serializable> implements GenericDao<T> {
protected Class<T> entityClass;
protected JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
....
@Override
public List<T> findAll(String sql, ParameterizedRowMapper<T> mapper, Object... args) {
return jdbcTemplate.query(sql, mapper, args);
}
}
This is a simple DAO.
这是一个简单的 DAO。
@Repository
public class ElementDaoImpl extends GenericDaoImpl<Element> implements ElementDao {
private static ParameterizedRowMapper<Element> mapper = new ParameterizedRowMapper<Element>() {...};
public List<Element> findChildren(int id) {
sql = "SELECT....";
return findAll(sql, mapper, new Object[] {id});
}
}
For moment, with unique datasource, it is working perfectly. The applicationContext is configured with annotation.
目前,凭借独特的数据源,它运行良好。applicationContext 是用注解配置的。
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/...."/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>
Now i have to integrate a new DAO still using genericDao, but working on another database (so another datasource).
现在我必须集成一个仍然使用 genericDao 的新 DAO,但是在另一个数据库上工作(所以另一个数据源)。
I use the @Transactionnal in service. And i read on spring documentation that we can give a qualifier to the transaction in order to select the good transaction manager.
我在服务中使用@Transactionnal。我阅读了 spring 文档,我们可以为交易提供一个限定符,以便选择好的交易管理器。
So, i create a new datasource, a new transaction manager...
所以,我创建了一个新的数据源,一个新的事务管理器......
<bean id="firstDS" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/...."/>
</bean>
<bean id="secondDS" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/...."/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="firstDS"/>
</bean>
<bean id="txManagerSecond" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="secondDS"/>
<qualifier value="txSecond"/>
</bean>
<tx:annotation-driven proxy-target-class="true"/>
and on my new Service, i have added the value to the @Transactionnal annotation :
在我的新服务中,我已将值添加到 @Transactionnal 注释中:
@Transactionnal("txSecond")
To resume, i have 4 classes to manage the new database : Interface for service, Implementation for service with @Transactionnal("txSecond"), Interface for DAO, Implementation for DAO based on genericDao which has a JdbcTemplate object created on an injected Datasource.
继续,我有 4 个类来管理新数据库:服务接口、@Transactionnal("txSecond") 服务实现、DAO 接口、基于 genericDao 的 DAO 实现,它具有在注入的数据源上创建的 JdbcTemplate 对象。
I created a Junit test, but for moment, i block on an exception : NoSuchBeanDefinitionException : no Unique bean of type javax.sql.DataSource is defined. Expected Single matching bean but found 2 (firstDs, SecondDs).
我创建了一个 Junit 测试,但暂时,我阻止了一个异常: NoSuchBeanDefinitionException :没有定义 javax.sql.DataSource 类型的唯一 bean。预期单个匹配 bean,但发现 2 个(firstDs、SecondDs)。
I think the pb is the genericDao but not sure.
我认为 pb 是 genericDao 但不确定。
How to manage that ?
如何管理?
Thank you.
谢谢你。
回答by willome
set manually your dataSource on each bean in your configuration file
在配置文件中的每个 bean 上手动设置数据源
<bean id="elementDao" class="ElementDaoImpl" autowire="byName">
<property name="datasource" ref="datasource2">
</bean>
An other solution : play with the "alias" http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#beans-java-bean-aliasing
回答by Sumit Desai
The problem is that while autowiring the datasource ,you have not specified any qualifier.
问题是在自动装配数据源时,您没有指定任何限定符。
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
}
So, if you need both your datasources in the same class, configure them using two different setter injections and provide appropriate qualifier in each case.
因此,如果您需要同一类中的两个数据源,请使用两个不同的 setter 注入配置它们,并在每种情况下提供适当的限定符。
回答by RK-Java
By default autowired annotation maps by typeof bean so one has to use qualifier("bean id")in order to let spring container know which bean to wire when multiple beans of the same type exist in config xml.
默认情况下,自动装配的注解按bean类型映射,因此当配置 xml 中存在多个相同类型的 bean 时,必须使用qualifier("bean id")以便让 spring 容器知道要连接哪个 bean。
回答by Vadzim
There is more elegant solution than adding qualifiers.
有比添加限定符更优雅的解决方案。
Spring: how to hide bean from dependency injection?
Autowiring two beans implementing same interface - how to set default bean to autowire?