Spring Multi-data source configuration
1. Add several data sources to the spring configuration file:
<bean id= "TestDataSource1" class= "Org.apache.commons.dbcp.BasicDataSource" >
<property name= "Driverclassname" value= "Oracle.jdbc.driver.OracleDriver"/>
<property name= "url" va Lue= "JDBC:ORACLE:THIN:@//127.0.0.1:1521/ORCL"/>
<property name= "username" value= "test1"/>
< Property name= "Password" value= "123456"/>
<property name= "maxactive" value= "/>";
<property Nam E= "Maxidle" value= "ten"/>
<property name= "maxwait" value= "" "/>
<property name=" Defaultautocomm It "value=" true "/>
</bean>
<bean id= "TestDataSource2" class= "Org.apache.commons.dbcp.BasicDataSource";
<property name= " Driverclassname "value=" Oracle.jdbc.driver.OracleDriver "/>
<property name=" url "value=" Jdbc:oracle:thin: @//127.0.0.1:1521/orcl "/>
<property name=" username "value=" test2 "/>
<property name=" Password "va Lue= "123456"/>
<property name= "maxactive" value= "/>";
<property name= "Maxidle" value= "ten"/> ;
<property name= "maxwait" value= "+"/>
<property name= "Defaultautocommit" value= "true"/>
& L T;/bean>,
2, and then combine the data sources:
<!--combined data source
<bean id= "DataSource" class= "Com.baoan.project.dao.hibernate.DynamicDataSource" >
<property name= "Targetdatasources" >
<map key-type= "Java.lang.String" >
<entry key= " TestDataSource1 "value-ref=" TestDataSource1 "/>
<entry key= " value-ref= "
</map>
</property>
<!--to a default data source configuration-
<property name= "Defaulttargetdatasource" ref= " TestDataSource1 " />
</bean>
3. Then expand a spring-provided abstractroutingdatasource,override which Determinecurrentlookupkey method implements the route of the data source.
[Java]
- Package datasource;
- Import Org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
- Public class Dynamicdatasource extends abstractroutingdatasource{
- @Override
- protected Object Determinecurrentlookupkey () {
- return Customercontextholder.getcustomertype ();
- }
- }
And Customercontextholder This is a developer's own implementation of a package of the threadlocal type of
Contextholder。
[Java]
- Package datasource;
- Public class Customercontextholder {
- public static final string data_source_a = "testdatasource1 " ;
- Public static final String data_source_a = "TestDataSource2";
- private static final threadlocal<string> Contextholder = new threadlocal<string> ();
- public static void Setcustomertype (String customertype) {
- Contextholder.set (CustomerType);
- }
- public static String Getcustomertype () {
- return Contextholder.get ();
- }
- public static void Clearcustomertype () {
- Contextholder.remove ();
- }
- }
5. How is this dynamic multi-data source used? Actually very simple, because our dynamicdatasource is inherited with Abstractroutingdatasource, And Abstractroutingdatasource is inherited in Org.springframework.jdbc.datasource.AbstractDataSource, the obvious Abstractdatasource realizes the unification Datasour Ce interface, so our dynamicdatasource can also be conveniently used as a DataSource, take hibernate below as an example:
[HTML]View Plaincopy
[Java]View Plaincopy
- <bean id="sessionfactory" class=" Org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean ">
- <!--can see the same as normal datasource usage--
- <property name="DataSource" ref="Dynamicdatasource"/>
- <property name="configlocations" value="Classpath:hibernate.cfg.xml"/>
- <property name="Hibernateproperties" >
- <props>
- <prop key="Hibernate.dialect" >${hibernate.dialect}</prop>
- </props>
- </property>
- </bean>
It can be seen that we are still using a sessionfactory, so the configuration of transaction management is the same as before.
[HTML]View Plaincopy
- <tx:annotation-driven transaction-manager="TransactionManager"/>
- <Bean id= "transactionmanager" class=" Org.springframework.orm.hibernate3.HibernateTransactionManager ">
- <property name= "sessionfactory" ref="sessionfactory" />
- </Bean>
The Dynamicdatasource Bean is also in the container, and now the rest is in the program to control how to choose a desired data source to do:
[Java]View Plaincopy
- This dynamically sets the data source to DATASOURCEB.
- Customercontextholder.setcustomertype (customercontextholder.data_source_b);
or using AOP to implement
[Java] view Plaincopy
- Package datasource;
- Import Org.aspectj.lang.JoinPoint;
- Import Org.aspectj.lang.annotation.Aspect;
- Import Org.aspectj.lang.annotation.Before;
- Import Org.aspectj.lang.annotation.Pointcut;
- @Aspect
- Public class Dynamicdatasourceaspect {
- @Pointcut ("Execution (public Service.impl). *.*(..))")
- public void Serviceexecution () {}
- @Before ("serviceexecution ()")
- public void Setdynamicdatasource (Joinpoint jp) {
- For (Object O:jp.getargs ()) {
- //Handle specific logic, according to the specific situation customercontextholder.setcustomertype () Select DataSource
- }
- }
- }
[Plain]View Plaincopy
- 6. Summary: We can see that the use of abstractroutingdatasource can be very good to implement a multi-data source, and later to expand more data sources is also very easy, as long as the data source and modify Dynamicdatasource The Bean's targetdatasources configuration is good. On the selection of a data source, in fact, can be very good with @aspect in the service entrance to join a plane @pointcut, In @before, judge the Joinpoint's class capacity to select a specific data source (for example, a more Joinpoint key to determine the setting Customercontextholder.setcustomertype).
- Genjiu the actual application to determine. Personal view: There have been many applications where Writedatasource and Readdatasource and Slavedatabase implementations have been deployed, but most of the applications are now less suited to the architecture, More and more attention and user interaction makes synchronization between the database become increasingly complex and difficult to maintain, so in the architecture of the system may consider the use of horizontal cutting method to cut the database, of course, this development needs more time to analyze the business domain, choose how to configure the data source is actually related to the business.
Spring configures multiple data sources