打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
基于druid和spring的动态数据库以及读写分离

spring与druid可以实现动态数据源,夸库查询,读写分离等功能。现在说一下配置:

1、需要配置多个spring数据源

spring-data.xml

Xml代码  
  1. <!-- 动态数据源 -->  
  2.     <bean id="dynamicDataSource" class="com.myproject.common.db.util.DynamicDataSource">  
  3.         <!-- 通过key-value关联数据源 -->  
  4.         <property name="targetDataSources">  
  5.             <map>  
  6.                 <entry value-ref="dataSourceWrite" key="dataSourceWrite"></entry>  
  7.                 <entry value-ref="dataSourceRead" key="dataSourceRead"></entry>  
  8.             </map>  
  9.         </property>  
  10.         <property name="defaultTargetDataSource" ref="dataSourceWrite" />  
  11.     </bean>  
  12.   
  13.     <!--mybatis与Spring整合 -->  
  14.     <bean id="sqlSessionFactory" name="sqlSessionFactory"  
  15.         class="org.mybatis.spring.SqlSessionFactoryBean">  
  16.         <property name="configLocation" value="classpath:mybatis.xml"></property>  
  17.         <property name="mapperLocations" value="classpath*:mapper/*.xml" />  
  18.         <property name="dataSource" ref="dynamicDataSource" />  
  19.     </bean>  
  20.   
  21.     <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">  
  22.         <constructor-arg index="0" ref="sqlSessionFactory" />  
  23.     </bean>  
  24.       
  25.       
  26.     <bean id="transactionManager"    
  27.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    
  28.         <property name="dataSource" ref="dynamicDataSource" />    
  29.     </bean>    
  30.       
  31.     <tx:annotation-driven transaction-manager="transactionManager" />   
  32.   
  33.     <!-- 数据源(DruidDataSource) -->  
  34.     <bean id="dataSourceWrite" class="com.alibaba.druid.pool.DruidDataSource"  
  35.         init-method="init" destroy-method="close">  
  36.         <property name="url" value="${urlOracle}" />  
  37.         <property name="username" value="${usernameOracle}" />  
  38.         <property name="password" value="${passwordOracle}" />  
  39.         <!-- 初始化连接大小 -->  
  40.         <property name="initialSize" value="5" />  
  41.         <!-- 连接池最大使用连接数量 -->  
  42.         <property name="maxActive" value="200" />  
  43.         <!-- 连接池最小空闲 -->  
  44.         <property name="minIdle" value="5" />  
  45.         <!-- 获取连接最大等待时间 -->  
  46.         <property name="maxWait" value="60000" />  
  47.         <!-- <property name="poolPreparedStatements" value="true" /> <property   
  48.             name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->  
  49.         <!-- <property name="validationQuery" value="${jdbc.validationQuery}" /> -->  
  50.         <property name="testOnBorrow" value="false" />  
  51.         <property name="testOnReturn" value="false" />  
  52.         <property name="testWhileIdle" value="true" />  
  53.         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
  54.         <property name="timeBetweenEvictionRunsMillis" value="60000" />  
  55.         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
  56.         <property name="minEvictableIdleTimeMillis" value="25200000" />  
  57.         <!-- 打开removeAbandoned功能 -->  
  58.         <property name="removeAbandoned" value="true" />  
  59.         <!-- 1800秒,也就是30分钟 -->  
  60.         <property name="removeAbandonedTimeout" value="1800" />  
  61.         <!-- 关闭abanded连接时输出错误日志 -->  
  62.         <property name="logAbandoned" value="true" />  
  63.         <!-- 监控数据库 -->  
  64.         <!-- <property name="filters" value="mergeStat" /> -->  
  65.         <property name="filters" value="stat" />  
  66.         <property name="defaultAutoCommit" value="true" />  
  67.     </bean>  
  68.       
  69.     <bean id="dataSourceRead" class="com.alibaba.druid.pool.DruidDataSource"  
  70.         init-method="init" destroy-method="close">  
  71.         <property name="url" value="${urlMysql}" />  
  72.         <property name="username" value="${usernameMysql}" />  
  73.         <property name="password" value="${passwordMysql}" />  
  74.         <!-- 初始化连接大小 -->  
  75.         <property name="initialSize" value="5" />  
  76.         <!-- 连接池最大使用连接数量 -->  
  77.         <property name="maxActive" value="200" />  
  78.         <!-- 连接池最小空闲 -->  
  79.         <property name="minIdle" value="5" />  
  80.         <!-- 获取连接最大等待时间 -->  
  81.         <property name="maxWait" value="60000" />  
  82.         <!-- <property name="poolPreparedStatements" value="true" /> <property   
  83.             name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->  
  84.         <!-- <property name="validationQuery" value="${jdbc.validationQuery}" /> -->  
  85.         <property name="testOnBorrow" value="false" />  
  86.         <property name="testOnReturn" value="false" />  
  87.         <property name="testWhileIdle" value="true" />  
  88.         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
  89.         <property name="timeBetweenEvictionRunsMillis" value="60000" />  
  90.         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
  91.         <property name="minEvictableIdleTimeMillis" value="25200000" />  
  92.         <!-- 打开removeAbandoned功能 -->  
  93.         <property name="removeAbandoned" value="true" />  
  94.         <!-- 1800秒,也就是30分钟 -->  
  95.         <property name="removeAbandonedTimeout" value="1800" />  
  96.         <!-- 关闭abanded连接时输出错误日志 -->  
  97.         <property name="logAbandoned" value="true" />  
  98.         <!-- 监控数据库 -->  
  99.         <!-- <property name="filters" value="mergeStat" /> -->  
  100.         <property name="filters" value="stat" />  
  101.         <property name="defaultAutoCommit" value="true" />  
  102.     </bean>  

 2、需要写一个DynamicDataSource类继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法

 

 

Java代码  
  1. public class DynamicDataSource extends AbstractRoutingDataSource {    
  2.         
  3.       
  4.     /**  
  5.      *   
  6.      * override determineCurrentLookupKey  
  7.      * <p>  
  8.      * Title: determineCurrentLookupKey  
  9.      * </p>  
  10.      * <p>  
  11.      * Description: 自动查找datasource  
  12.      * </p>  
  13.      *   
  14.      * @return  
  15.      */    
  16.     @Override    
  17.     protected Object determineCurrentLookupKey() {    
  18.         return DBContextHolder.getDSType();    
  19.     }    
  20.     
  21. }    

 

 

3、参考spring事务管理,使用线程变量来切换数据源

 

Java代码  
  1. public class DBContextHolder {  
  2.   
  3.     /** 
  4.      * 线程threadlocal 
  5.      */  
  6.     private static ThreadLocal<String> contextHolder = new ThreadLocal<>();  
  7.     private static Logger logger = LoggerFactory  
  8.             .getLogger(DBContextHolder.class);  
  9.   
  10.     public static String getDSType() {  
  11.         try {  
  12.   
  13.         } catch (Exception e) {  
  14.             e.printStackTrace();  
  15.             logger.error("get DBTYPE faild with error:[" + e.getMessage() + "]");  
  16.         }  
  17.   
  18.         String db = contextHolder.get();  
  19.          if (db == null) {  
  20.          db =UrlConnect.getKey(ConfigHelper.getToWriteKey());// 默认是读写库  
  21.          }  
  22.         return db;  
  23.     }  
  24.   
  25.     /** 
  26.      *  
  27.      * 设置本线程的dbtype 
  28.      *  
  29.      * @param str 
  30.      * @see [相关类/方法](可选) 
  31.      * @since [产品/模块版本](可选) 
  32.      */  
  33.     public static boolean setDSType(String str) {  
  34.         try {  
  35.             clearDBType();  
  36.             if (str != null&&!str.equals("")) {  
  37.                 contextHolder.set(str);  
  38.                 logger.info("change thread[" + str + "] success!");  
  39.                 return true;  
  40.             } else {  
  41.                 logger.info("change thread[" + str + "] faild!");  
  42.                 return false;  
  43.             }  
  44.         } catch (Exception e) {  
  45.             e.printStackTrace();  
  46.             logger.error("change thread[" + str + "] faild!");  
  47.             return false;  
  48.         }  
  49.     }  
  50.   
  51.     /** 
  52.      * clearDBType 
  53.      *  
  54.      * @Title: clearDBType 
  55.      * @Description: 清理连接类型 
  56.      */  
  57.     public static void clearDSType() {  
  58.         contextHolder.remove();  
  59.     }  
  60. }  

 

 

4、在dao中切换数据源

Java代码  
  1. @Repository  
  2. public class BaseDAO extends SqlSessionDaoSupport {  
  3.        @Resource  
  4.     private SqlSessionTemplate sqlSessionTemplate;  
  5. @Resource  
  6.     public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {  
  7.         super.setSqlSessionTemplate(sqlSessionTemplate);  
  8.     }  
  9.   
  10. public  <T> PageList<T> selectPublicListPage(String countSqlID,String sqlID,  
  11.             PageList<T> page, Object obj) {  
  12.         DBContextHolder.setDbType("dataSourceRead");  
  13.         //查询总数  
  14.         Integer total = this.getSqlSession().selectOne(countSqlID, obj);  
  15.         RowBounds rowBounds=new RowBounds(page.getFirstResult(),page.getPageSize());  
  16.         // 查询列表信息  
  17.         List<T> list = this.getSqlSession().selectList(  
  18.                 sqlID, obj,rowBounds);  
  19.         page.setTotalRecord(total!=null?total:0);  
  20.         page.setDataSource(list);  
  21.         page.setTotalPage((total + page.getPageSize() - 1)  
  22.                 / page.getPageSize());  
  23.         return page;  
  24.     }  
  25.   
  26.     public int insert(String sqlID, Object paramObj) {  
  27.         DBContextHolder.setDbType("dataSourceWrite");  
  28.         return this.getSqlSession().insert(sqlID, paramObj);  
  29.     }  
  30.   
  31.   
  32. }  

 

 

 

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Spring多数据源的配置和使用
spring,mybatis,atomikos多数据源的整合
druid:保存监控记录
Struts2标签调用类中的函数
sqlserver的相关东西
springmvc commandClass 和 commandName
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服