出處:http://www.cnblogs.com/coveted/archive/2011/10/22/2221317.html
起因:在當前我手上的一個項目中需要多個數據源,並且來自於不同類型的數據庫... 因爲很多歷史原因.這個項目的住數據源是MySQL,整個系統的CURD都是操作的這個數據庫.
package lhp.example.context; public enum DBType { dataSource1, dataSource2; }
package lhp.example.context; public class ContextHolder { private static final ThreadLocal<Object> holder = new ThreadLocal<Object>(); public static void setDbType(DBType dbType) { holder.set(dbType); } public static DBType getDbType() { return (DBType) holder.get(); } public static void clearDbType() { holder.remove(); } }
package lhp.example.context; import java.util.logging.Logger; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { public static final Logger logger = Logger.getLogger(DynamicDataSource.class.toString()); @Override protected Object determineCurrentLookupKey() { DBType key = ContextHolder.getDbType();//獲得當前數據源標識符 //logger.info("當前數據源 :" + key); return key; } }
<!-- 數據源1 : mysql --> <bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/dec" /> <property name="user" value="root" /> <property name="password" value="" /> </bean> <!-- 數據源2 : mysql --> <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/lms" /> <property name="user" value="root" /> <property name="password" value="" /> </bean> <!-- 數據源3 : access --> <bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="sun.jdbc.odbc.JdbcOdbcDriver" /> <property name="jdbcUrl" value="jdbc:odbc:accessTest" /> <property name="user" value="administrator" /> <property name="password" value="XLZX0309" /> </bean> <!-- mysql 動態數據源設置--> <bean id="mysqlDynamicDataSource" class="lhp.example.context.DynamicDataSource"> <property name="targetDataSources"> <!-- 標識符類型 --> <map key-type="lhp.example.context.DBType"> <entry key="dataSource1" value-ref="dataSource1" /> <entry key="dataSource2" value-ref="dataSource2" /> </map> </property> <property name="defaultTargetDataSource" ref="dataSource1" /> </bean>
<!-- mysql sessionFactory --> <bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="mysqlDynamicDataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop><!--create validate --> <prop key="hibernate.query.substitutions">true 1, false 0</prop> </props> </property> </bean> <!-- access sessionFactory --> <bean id="aceessSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource3" /> <property name="hibernateProperties"> <props> <!-- access 語法和MSSQL相似 所以用的MSSQL方言,或者可以使用第三方方言 --> <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop> <prop key="hibernate.jdbc.batch_size">30</prop> <prop key="hibernate.jdbc.fetch_size">50</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">false</prop> <prop key="hibernate.hbm2ddl.auto">update</prop><!--create validate --> <prop key="hibernate.query.substitutions">true 1, false 0</prop> <prop key="hibernate.cglib.use_reflection_optimizer">true</prop> <!-- <prop key="hibernate.cache.use_second_level_cache">true</prop> --> <!-- <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> --> <!-- <prop key="hibernate.cache.use_query_cache">true</prop> --> <!-- <prop key="hibernate.generate_statistics">true</prop> --> <!-- <prop key="hibernate.cache.provider_configuration_file_resource_path">classpath:ehcache.xml</prop> --> </props> </property> </bean>
package lhp.example.junit; import static org.junit.Assert.*; import java.sql.DatabaseMetaData; import lhp.example.context.ContextHolder; import lhp.example.context.DBType; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ServiceTest { private ApplicationContext context; //三個數據源的URL private String dataSource1_URL = "jdbc:mysql://127.0.0.1:3306/dec"; private String dataSource2_URL = "jdbc:mysql://127.0.0.1:3306/lms"; private String dataSource3_URL = "jdbc:odbc:accessTest"; private SessionFactory mysqlSessionFactory; private SessionFactory aceessSessionFactory; @Before public void setUp() throws Exception { // 選擇數據源初始化spring ContextHolder.setDbType(DBType.dataSource1); // String[] xmlFiles = new String[] { "applicationContext-dataSource.xml", "applicationContext-hibernate.xml", "applicationContext-spring.xml" }; // context = new ClassPathXmlApplicationContext(xmlFiles); // mysqlSessionFactory = (SessionFactory) context.getBean("mysqlSessionFactory"); aceessSessionFactory = (SessionFactory) context.getBean("aceessSessionFactory"); } @SuppressWarnings("deprecation") @Test public void mysqlDataSourceTest() { try { Session mysqlSession = mysqlSessionFactory.openSession(); // 獲得數據庫元數據 DatabaseMetaData meatData = mysqlSession.connection().getMetaData(); // 默認啓動數據源 dataSource1 //斷言當前數據源URL是否是dataSource1的URL assertEquals(dataSource1_URL, meatData.getURL()); // 切換到數據源 dataSource2 ContextHolder.setDbType(DBType.dataSource2); mysqlSession = mysqlSessionFactory.openSession(); meatData = mysqlSession.connection().getMetaData(); //斷言當前數據源URL是否是dataSource2的URL assertEquals(dataSource2_URL, meatData.getURL()); } catch (Exception e) { e.printStackTrace(); } } @SuppressWarnings("deprecation") @Test public void accessDataSourceTest() { try { Session accessSession = aceessSessionFactory.openSession(); // 獲得數據庫元數據 DatabaseMetaData meatData = accessSession.connection().getMetaData(); //斷言當前數據源URL是否是dataSource3的URL assertEquals(dataSource3_URL, meatData.getURL()); } catch (Exception e) { e.printStackTrace(); } } }