Spring:如何使用GenericDao获取多个数据源? [英] Spring : how to get multiple datasource with GenericDao?

查看:171
本文介绍了Spring:如何使用GenericDao获取多个数据源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用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);
}

}

这是一个简单的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});
    }

}

暂时,凭借独特的数据源,它可以完美运行. 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"/>

现在,我必须仍然使用genericDao集成一个新的DAO,但是要在另一个数据库上工作(因此是另一个数据源).

我在使用@Transactionnal.我阅读了Spring文档,我们可以为交易指定条件,以便选择优秀的交易管理器.

因此,我创建了一个新的数据源,一个新的事务管理器...

<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"/>

在我的新服务上,我已将该值添加到@Transactionnal批注中:

 @Transactionnal("txSecond")

要继续,我有4个类来管理新数据库:服务接口,@Transactionnal("txSecond")服务实现,DAO接口,基于genericDao的DAO实现,该类在JD上创建了JdbcTemplate对象.注入的数据源.

我创建了一个Junit测试,但是暂时,我阻止了一个异常:NoSuchBeanDefinitionException:没有定义类型javax.sql.DataSource的唯一bean.应该是单个匹配的Bean,但是找到了2个(firstD,SecondD).

我认为pb是genericDao,但不确定.

如何管理?

谢谢.

解决方案

在配置文件中的每个bean上手动设置数据源

<bean id="elementDao" class="ElementDaoImpl" autowire="byName">
   <property name="datasource" ref="datasource2">
</bean>

另一个解决方案:使用别名"

For moment, with unique datasource, it is working perfectly. The applicationContext is configured with annotation.

<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).

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.

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("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.

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).

I think the pb is the genericDao but not sure.

How to manage that ?

Thank you.

解决方案

set manually your dataSource on each bean in your configuration file

<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

这篇关于Spring:如何使用GenericDao获取多个数据源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆