views:

926

answers:

5

Is it possible to define a datasource connector in a Spring controller ?

I'm working on a tool : synchronize a source table to a target table.
I would define source and target in my controller (to synchronize different databases - in my view I can select different source and target databases).

Actually, I define my datasource in file call : datasource.xml

My code :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd"&gt;

    <context:annotation-config />

    <bean id="sourceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
     <property name="url" value="jdbc:mysql://localhost/source"/>
     <!--<property name="url" value="jdbc:mysql://linkSource"/>-->
     <property name="username" value="username"/>
     <property name="password" value="password"/>
    </bean>

        <bean id="targetDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
     <property name="url" value="jdbc:mysql://localhost/target"/>
     <!--<property name="url" value="jdbc:mysql://linkTarget"/>-->
     <property name="username" value="username"/>
     <property name="password" value="password"/>
    </bean>

</beans>

Thank you for your help !

A: 

You should be able to use the following syntax to achieve what you want (see Spring 2.x docs):

@Autowired
@Qualifier("targetDataSource")
DataSource targetDataSource;

@Autowired
@Qualifier("sourceDataSource")
DataSource sourceDataSource;
Rich Kroll
A: 

So assuming your data sources are defined correctly it's only a matter of injecting them into your Controller:

<bean id="myController" class="...">
   <property name="sourceDS" ref="sourceDataSource" />
   <property name="targetDS" ref="targetDataSource" />
   ....
</bean>
Gandalf
If I have more than one target (could be 5 targets), what is the best to select the good target in my controller ?A factory is it a good idea ?
Fabien Barbier
A: 

Thank you for your help ! But I think I put my question badly.

Actually, I have in my sync-servelt.xml (just part) :

        <!--sync query beans-->
        <bean id="sourceDatasetQueryBean" class="ds.sync.db.SyncDatasetQuery" name="sourceDatasetsQuery">
            <property name="dataSource" ref="sourceDataSource"/>
        </bean>

        <bean id="targetDatasetQueryBean" class="ds.sync.db.SyncDatasetQuery" name="targetDatasetsQuery">
            <property name="dataSource" ref="targetDataSource"/>
        </bean>

        <bean id="sourceDatasetDescriptionQueryBean" class="ds.sync.db.SyncDatasetDescriptionQuery" name="sourceDatasetsDescriptionQuery">
            <property name="dataSource" ref="sourceDataSource"/>
        </bean>

        <bean id="targetDatasetDescriptionQueryBean" class="ds.sync.db.SyncDatasetDescriptionQuery" name="targetDatasetsDescriptionQuery">
            <property name="dataSource" ref="targetDataSource"/>
        </bean>
...more...

And, in my controller I'm using :

 @Autowired
 @Qualifier("sourceDatasetQueryBean")
 protected SyncDatasetQuery m_datasetQuerySource;

 @Autowired
 @Qualifier("targetDatasetQueryBean")
 protected SyncDatasetQuery m_datasetQueryTarget;

 @Autowired
 @Qualifier("sourceDatasetDescriptionQueryBean")
 protected SyncDatasetDescriptionQuery m_datasetDescriptionQuerySource;

 @Autowired
 @Qualifier("targetDatasetDescriptionQueryBean")
 protected SyncDatasetDescriptionQuery m_datasetDescriptionQueryTarget;
...more...

I have 11 tables to sync between source and target...
Is there a way to group my query beans ?

My synchronizations must be performed on several databases.
For example, I have 3 sites in different places, 1 site is SOURCE (A), 2 sites are TARGET (B & C) ; with a form (made with YUI), I should be able to sync A->B and A->C.
To sum up :
1- with my form I select a SOURCE, and a TARGET (serveral databases),
2- my form send (in Ajax), the selected SOURCE and selected TARGET to my controller,
3- my controller points to the good database.

What is the best way to do this ?
Using a Factory ? Using setDataSource ?
Thank you for help.

Fabien Barbier
A: 

If you don't want to be messing with spring xml files, and relay in properties or any other GUI to define those datasources at runtime, you might use:

applicationContext.getBean(bean,object[])

Be aware that is not a good practise with spring (even that it is quite handy sometimes). This way you define your beans expecting constructor arguments and supply those arguments as part of the array. This way you create as many datasources you need at runtime getting those from wherever you want to store the information.

pedromarce
A: 

Finally, by using DriverManagerDataSource, and using setter, I can redefine my dataSource selected (target and source) dynamically in my controller.

I just need to use : setDriverManagerDataSource(m_sourceDataSource); and m_datasetQuerySource.setDataSource(dataSource); (SOURCE)

Same play with target and all tables.

I see also other way to do that : http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/ http://grails.org/Spring+Bean+Builder

Fabien Barbier