1炭剪、創(chuàng)建動態(tài)數(shù)據(jù)源RoutingDataSource
package com.yhbc.datasourceT;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.SessionFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import com.alibaba.druid.pool.DruidDataSource;
//@Component? 不能有這個注解 练链,xml的bean比他晚生成
public class RoutingDataSource extends AbstractRoutingDataSource? {
private? Map dataSources = new HashMap<>();
//@Autowired
//@Qualifier("dataSource")//根據(jù)xml的id寫
private DruidDataSource defaultTargetDataSource ;//主數(shù)據(jù)源注入
JdbcTemplate jdbcTemplate;
protected SessionFactory sessionFactory;
@Override
protected DataSource determineTargetDataSource() {
// 根據(jù)數(shù)據(jù)庫選擇方案,拿到要訪問的數(shù)據(jù)庫
? ? ? ? String dataSourceName = (String) determineCurrentLookupKey();
? ? ? ? if(RoutingDataSourceContext.MASTER_DATASOURCE.equals(dataSourceName)) {
? ? ? ? ? ? // 訪問默認(rèn)主庫
? ? ? ? ? ? return defaultTargetDataSource;
? ? ? ? }
? ? ? ? // 根據(jù)數(shù)據(jù)庫名字奴拦,從已創(chuàng)建的數(shù)據(jù)庫中獲取要訪問的數(shù)據(jù)庫
? ? ? ? return (DataSource) this.dataSources.get(dataSourceName);
}
@Override
? ? protected Object determineCurrentLookupKey() {
? ? System.out.println("---determineCurrentLookupKey-----主數(shù)據(jù)源=="+defaultTargetDataSource);
? ? ? ? String dbName = RoutingDataSourceContext.getDataSourceRoutingKey();
? ? ? ? if (StringUtils.isEmpty(dbName)) {
? ? ? ? return RoutingDataSourceContext.getMainKey();
? ? ? ? }
? ? ? ? if (!dataSources.containsKey(dbName)){
? ? ? ? ? ? createAndSaveDataSource(dbName);
? ? ? ? }
? ? ? ? return dbName;
? ? }
? ? private synchronized void createAndSaveDataSource(String dbName) {
? ? ? ? DruidDataSource dataSource = createDruidDataSource(dbName);
? ? ? ? dataSources.put(dbName, dataSource);
? ? ? ? super.setTargetDataSources(dataSources);
? ? ? ? afterPropertiesSet();
? ? }
? ? /**
? ? * 根據(jù)配置創(chuàng)建DruidDataSource
? ? * @param fanDataSource
? ? * @return
? ? */
? ? public? DruidDataSource createDruidDataSource(String dbName ) {
? ? if(dataSources.containsKey(dbName)){
? ? return (DruidDataSource) dataSources.get(dbName);
? ? }
? ? ? ? DruidDataSource dataSource = new DruidDataSource();
? ? ? ? dataSource.setDriverClassName("com.mysql.jdbc.Driver");
? ? ? ? dataSource.setName(dbName);
? ? ? ? dataSource.setUrl("jdbc:mysql://192.168.1.13:3306/"+dbName+"?useUnicode=true&allowMultiQueries=true&useSSL=false");
? ? ? ? dataSource.setUsername("root");
? ? ? ? dataSource.setPassword("root");
? ? ? ? dataSource.setInitialSize(2);
? ? ? ? // 從池中取得鏈接時做健康檢查媒鼓,該做法十分保守
? ? ? ? dataSource.setTestOnBorrow(true);
? ? ? ? // 如果連接空閑超過1小時就斷開
? ? ? ? dataSource.setMinEvictableIdleTimeMillis(1 * 60000 * 60);
? ? ? ? // 每十分鐘驗(yàn)證一下連接
? ? ? ? dataSource.setTimeBetweenEvictionRunsMillis(600000);
? ? ? ? // 運(yùn)行ilde鏈接測試線程,剔除不可用的鏈接
? ? ? ? dataSource.setTestWhileIdle(true);
? ? ? ? dataSource.setMaxWait(-1);
? ? ? ? return dataSource;
? ? }
? ? /*public RoutingDataSource() {
? ? //創(chuàng)建主庫
? ? ? // createAndSaveDataSource(RoutingDataSourceContext.getMainKey());
? ? ? ? dataSources.put(RoutingDataSourceContext.MASTER_DATASOURCE,defaultTargetDataSource );
? ? ? ? System.out.println("構(gòu)造動態(tài)數(shù)據(jù)源粱坤,加入主數(shù)據(jù)源=="+defaultTargetDataSource);
? ? ? ? DruidDataSource dataSource = createDruidDataSource();
? ? ? ? jdbcTemplate = new JdbcTemplate();
? ? ? ? jdbcTemplate.setDataSource(dataSource);
? ? ? ? System.out.println("===========testQy========="+testQy());
? }*/
? ? /**
? ? * 通過jdbc從數(shù)據(jù)庫中查找數(shù)據(jù)源配置
? ? * @param name
? ? * @return
? ? */
? ? private int testQy() {
? ? ? ? String sql = "select id? from box_function? where url='1-supplyCodeList.htm' ";
? ? ? // RowMapper<FanDataSource> rowMapper = new BeanPropertyRowMapper<>(FanDataSource.class);
? ? ? ? int? id = jdbcTemplate.queryForInt(sql);
? ? ? ? return id;
? ? }
public void setDefaultTargetDataSource(DruidDataSource defaultTargetDataSource) {
System.out.println("---setDefaultTargetDataSource-----主數(shù)據(jù)源=="+defaultTargetDataSource);
this.defaultTargetDataSource = defaultTargetDataSource;
}
}
2隶糕、創(chuàng)建線程切換類RoutingDataSourceContext瓷产,用來切換數(shù)據(jù)庫的名稱
package com.yhbc.datasourceT;
public class RoutingDataSourceContext? {
? ? static final ThreadLocal<String> threadLocalDataSourceKey = new ThreadLocal<>();
? ? public static final String MASTER_DATASOURCE="defaultDataSource";
? ? /**
? ? * 獲取主數(shù)據(jù)庫的key
? ? * @return
? ? */
? ? public static String getMainKey() {
? ? ? ? return MASTER_DATASOURCE;
? ? }
? ? /**
? ? * 獲取數(shù)據(jù)庫key
? ? * @return
? ? */
? ? public static String getDataSourceRoutingKey() {
? ? ? ? String key = threadLocalDataSourceKey.get();
? ? ? ? return key == null ? getMainKey() : key;
? ? }
? ? /**
? ? * 設(shè)置數(shù)據(jù)庫的key
? ? * @param key
? ? */
? ? public static void setThreadLocalDataSourceKey(String key) {
? ? ? ? threadLocalDataSourceKey.set(key);
? ? }
}
3站玄、關(guān)鍵的一步,數(shù)據(jù)源關(guān)聯(lián)session
仔細(xì)觀察哦濒旦,routingDataSource在bean中株旷,賦予sessionFactory
<beans:bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<beans:property name="driverClassName" value="${silverbox.driver}" />
<beans:property name="url" value="${silverbox.url}" />
<beans:property name="username" value="${silverbox.username}" />
<beans:property name="password" value="${silverbox.password}" />
<beans:property name="maxActive" value="${silverbox.maxActive}" />
<beans:property name="validationQuery" value="${silverbox.testSql}"/>
<beans:property name="testWhileIdle" value="true"/>
<beans:property name="initialSize" value="${silverbox.initialSize}"/>
<beans:property name="maxWait" value="${silverbox.maxWait}"/>
</beans:bean>
<beans:bean id="routingDataSource" class="com.yhbc.datasourceT.RoutingDataSource">
<beans:property name="targetDataSources">
<beans:map key-type="java.lang.String">
<beans:entry key="defaultDataSource" value-ref="dataSource" />
</beans:map>
</beans:property>
<beans:property name="defaultTargetDataSource" ref="dataSource" ></beans:property>
</beans:bean>
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- <beans:property name="dataSource" ref="dataSource" /> -->
<beans:property name="dataSource" ref="routingDataSource" />
<beans:property name="packagesToScan">
<beans:list>
<beans:value>com.yhbc.entity</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:value>
hibernate.dialect= org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
hibernate.format_sql=false
hibernate.query.substitutions=true 1, false 0
hibernate.jdbc.batch_size=20
hibernate.cache.use_query_cache=false
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.search.default.directory_provider=filesystem
hibernate.search.default.indexBase=d:\\index
</beans:value>
</beans:property>
</beans:bean>
4、測試尔邓,接下來在control中切換調(diào)用:
@RequestMapping(value = { "/hybd-findfunction.htm" }, produces = "text/html;charset=UTF-8")
? ? @ResponseBody
? ? public String findfunction(String functionUsername,String dbtype) {
? ? JSONObject jo=new JSONObject();
? ? log.info("-----------------------------/hybd-add.htm");
? ? ? ? try {
? ? ? ? //silverbox_backup
? ? ? ? /*Dbs.setDbType("backup");
? ? ? ? dynamicDataSource.determineTargetDataSource();*/
? ? ? ? if(dbtype!=null){
? ? ? ? //切換數(shù)據(jù)源晾剖,dbtype是數(shù)據(jù)庫名稱哦,這里的所有數(shù)據(jù)源默認(rèn)都是相同的host梯嗽,只是庫的區(qū)別
? ? ? ? RoutingDataSourceContext.setThreadLocalDataSourceKey(dbtype);
? ? ? ? }
? ? System.out.println("sessionFactory==="+sessionFactory.toString());
? ? ? ? List<?> list=this.hYBDService.findFunction(functionUsername);
? ? ? ? jo.put("msg", "添加成功");
? ? ? ? jo.put("list", list);
? ? ? ? jo.put("success", true);
? ? ? ? } catch (Exception e) {
? ? ? ? jo.put("success", false);
? ? ? ? ? e.printStackTrace();
? ? ? ? ? log.error("error---hybd-add.htm-----:"+Utils.log4jDetail(e));
? ? ? ? }
? ? ? ? return jo.toJSONString();
? ? }
親測通過哦齿尽,如果有用請多多支持哦