The following is a combination of project consolidation how to achieve the spring data routing dynamic switching, divided into three parts, 1. configuration file. 2.java class. 3. Summary
One: Configuration file
Dataant.properties:
Driverclass1=oracle.jdbc.driver.oracledriver
Jdbcurl1=jdbc\:oracle\:thin\:@136.160.40.36\:1521\:crmtemp
db.user1=crm_app
db.password1=abc123
driverclass2=oracle.jdbc.driver.oracledriver
jdbcUrl2= Jdbc\:oracle\:thin\:@136.160.40.36\:1521\:crmtest
Db.user2=crm_app
db.password2=abc123
Configuration file, two JDBC configuration
Sm-spring-db.xml:
<!--dataant default data Source-<bean id= "Smdatasource" class= "Org.apache.commons.dbcp.BasicDataSource" destroy-method= "Close" > <property name= "driverclassname" value= "${driverclass1}" > </property> <PR Operty name= "url" value= "${jdbcurl1}" > </property> <property name= "username" value= "${db.user1}" > < ;/property> <property name= "password" value= "${db.password1}" > </property> <property name= "Accesst Ounderlyingconnectionallowed "> <value>true</value> </property> </bean> <!--number of data migration targets According to source--<bean id= "Qydatasource" class= "Org.apache.commons.dbcp.BasicDataSource" destroy-method= "Close" > < Property Name= "Driverclassname" value= "${driverclass2}" > </property> <property name= "url" value= "${ JDBCURL2} "> </property> <property name=" username "value=" ${db.user2} "> </property> <proper Ty name= "password" value= "${db.password2}" > </property> <property name= "accesstounderlyingconnectionallowed" > <value>true</value> </pr Operty> </bean> <!--data routing datasource--> <bean id= "DataSource" class= "com.ai.data.common.LinkageRout Ingdatasource "> <property name=" targetdatasources "> <map key-type=" java.lang.String "> <entry VA lue-ref= "Smdatasource" key= "Smdatasource" ></entry> <entry value-ref= "Qydatasource" key= "Qydatasource" ></entry> </map> </property> <property name= "Defaulttargetdatasource" ref= "Smdatasource" ;</property> <!--use DS1 data source by default-</bean>
1. Here, two data source Smdatasource,qydatasource are configured, and routing switching is implemented through the class Linkageroutingdatasource class. Note that the Bean ID is set to DataSource, which guarantees that the following objects are controlled to the corresponding data source.
2.bean id = ' DataSource ' Note that the target data source Targetdatasource and Defaulttargetdatasource must be set.
Injection JdbcTemplate Tool Class:
<!--injection JdbcTemplate switch DataSource tool class [Get bean name, reset DataSource]--
<bean class= " Com.ai.data.common.JdbcTemplateUtil "></bean>
II: Java class
Linkageroutingdatasource.java
Package Com.ai.data.common;
Import Org.apache.commons.lang.StringUtils;
Import Org.arrow.common.utils.Log;
Import Org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * Set Data source * * @author Weiweiai * @see [Related Classes/methods] (optional) * @since [Product/module version] (optional) */public class LINKAGEROUTINGDATASOURC
E extends Abstractroutingdatasource {private static final log log = Log.getlog (Linkageroutingdatasource.class);
Target data source private static final threadlocal<string> Target_data_source = new threadlocal<string> ();
Default data source--public static final String Default_data_source = "Smdatasource" for indicator monitoring; /** * Data source switching based on the current thread data source set in Prvncutil class * * @param no * @return Data Source Name */protected Object Determinecurrentlook
Upkey () {String Targetdatasource = Target_data_source.get (); if (Stringutils.isempty (Targetdatasource)) {targetdatasource = Default_data_source;//The default data source monitors the data source for metrics Target_data_sou
Rce.set (Targetdatasource); } log.debug ("Current thread data source----------------:{} ", Targetdatasource);
return targetdatasource; }/** * Set data source name * @param target */public static void Settargetdatasource (String target) {Target_da
Ta_source.set (target);
}/** * Fetch data Source name * @return */public static String Gettargetdatasource () {return target_data_source.get (); }
}
1. Implement the Abstractroutingdatasource abstract class provided by spring, using the Threadlocal type to define the Target_data_source (target data source) to ensure that the data source names between threads do not affect each other.
2. Specify the default data source name, corresponding to the bean id = ' Smdatasource ' in the first step
3.determineCurrentLookupKey This method, personal understanding, as follows: The meaning should be that code to establish a data source connection, this method will be executed to find the appropriate data source.
The code here is to take the thread-safe target_data_source of the Target_data_source thread variable first, not to use the default data source Smdatasource. This implements the Bean id= ' dataSource ' attribute targetdatasources switch.
Prvncutil.java
Package Com.ai.data.common;
Import Org.apache.commons.lang.StringUtils;
Import Org.arrow.common.utils.Log; /** * Set gets the current thread data source name * * @date 20150924 * @author Weiweiai */public class Prvncutil {private static final Log LO
G_output = Log.getlog (Prvncutil.class);
Default data source public static final String Default_data_source = "Smdatasource"; /** * Set the data source name to use * * @param datasourcename Data Source Name * @retrun None */public static void Setdatas Ourcename (String datasourcename) {Linkageroutingdatasource.settargetdatasource (Getdatasourcename (DataSourceName)
); /** * Gets the data source name * @param datasourcename * @return Data Source name */public static String GetData
SourceName (String datasourcename) {string dataSource = DataSourceName;
if (Stringutils.isempty (DataSource)) {dataSource = Default_data_source;
} log_output.debug ("Finally gets the current data source name: {}", DataSource); ((JdbcTemplate) Springcontextholder.getbean ("JDBctemplate ")). Setdatasource ((DataSource) Springcontextholder.getbean (DataSource));
return dataSource; }
}
Data Routing Switch Tool class
Jdbctemplateutil.java
Package Com.ai.data.common;
Import Javax.sql.DataSource;
Import org.springframework.beans.BeansException;
Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.ApplicationContextAware;
Import Org.springframework.jdbc.core.JdbcTemplate;
Import Com.linkage.bss.commons.util.StringUtil; /** * JdbcTemplate Tool class, implement JdbcTemplate data source reset after switching data source * @author Weiweiai * 2016/5/10 * */public class Jdbctemplateutil Imp
Lements applicationcontextaware{@Autowired private JdbcTemplate jdbctemplate;
public void Setjdbctemplate (JdbcTemplate jdbctemplate) {this.jdbctemplate = JdbcTemplate;
} private ApplicationContext CTX; /* * (non-javadoc) * @see Org.springframework.context.applicationcontextaware#setapplicationcontext ( ORG.SPRINGFRAMEWORK.CONTEXT.APPLICATIONCONTEXT) */public void Setapplicationcontext (ApplicationContext ApplicationContext) throws Beansexception {//TODO auto-Generated method stub this.ctx = ApplicationContext; }/* * Take linkageroutingdatasource thread variable in data source, reset JdbcTemplate Data Source Property */Public JdbcTemplate getjdbctemplate () {String
ds = Linkageroutingdatasource.gettargetdatasource (); if (!
Stringutil.isempty (DS)) Jdbctemplate.setdatasource ((DataSource) Ctx.getbean (DS));
return jdbctemplate; }
}
1. Implement the Applicationcontextaware interface and have been introduced in the first step to get the beans injected into the spring container.
2.getJdbcTemplate () method, first gets the data source name saved in the Target_data_source thread variable in the Linkageroutingdatasource class.
3.ds is empty, the default data source is returned, otherwise the JdbcTemplate data source is switched.
Call:
Prvncutil.setdatasourcename ("Qydatasource");
Primaryvaluelist = Jdbctemplateutil.getjdbctemplate (). queryForList ((String) datamap.get ("Selforprimary"));
Three: summary
Prvncutil.setdatasourcename ("Qydatasource");
Switches are implemented:
Primaryvaluelist = Jdbctemplateutil.getjdbctemplate (). queryForList ((String) datamap.get ("Selforprimary"));
Implemented:
Here why JdbcTemplate already pointed to DataSource. And DataSource has changed the properties Targetdatasource but useless, I do not understand, welcome the great God guiding reasons. I've been trying, and I really need a hand.
Jdbctemplate.setdatasource ((DataSource) Ctx.getbean (DS))
Otherwise the data source cannot be cut and verified.