国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

mysql+spring+mybatis實現數據庫讀寫分離的代碼配置

2024-07-14 08:43:47
字體:
來源:轉載
供稿:網友

場景:一個讀數據源一個讀寫數據源。

原理:借助spring的【org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource】這個抽象類實現,看名字可以了解到是一個路由數據源的東西,這個類中有一個方法

/**  * Determine the current lookup key. This will typically be  * implemented to check a thread-bound transaction context.  * <p>Allows for arbitrary keys. The returned key needs  * to match the stored lookup key type, as resolved by the  * {@link #resolveSpecifiedLookupKey} method.  */ protected abstract Object determineCurrentLookupKey(); 

每次去連數據庫的時候,spring會調用這個方法去找對應的數據源。返回值即對應的數據源的LookUpKey.那么這個LookUpKey在哪定義的呢?看下面的dataBase.xml的配置

<!--數據源 讀寫 --> <bean id="dataSourceRW" class="org.logicalcobwebs.proxool.ProxoolDataSource">   <property name="alias" value="ihotelRW"></property>   <property name="delegateProperties">     <value>user=${jdbc.username},password=${jdbc.password}     </value>   </property>   <property name="user" value="${jdbc.username}" />   <property name="password" value="${jdbc.password}" />   <property name="driver" value="${jdbc.driverClassName}" />   <property name="driverUrl" value="${jdbc.url}" />   <property name="maximumConnectionCount" value="${jdbc.maximumConnectionCount}"></property>   <property name="maximumActiveTime" value="${jdbc.maximumActiveTime}"></property>   <property name="maximumConnectionLifetime" value="${jdbc.maximumConnectionLifetime}"></property>   <property name="prototypeCount" value="${jdbc.prototypeCount}"></property>   <property name="houseKeepingSleepTime" value="${jdbc.houseKeepingSleepTime}"></property>   <property name="simultaneousBuildThrottle" value="${jdbc.simultaneousBuildThrottle}"></property>   <property name="houseKeepingTestSql" value="${jdbc.houseKeepingTestSql}"></property>   <property name="verbose" value="${jdbc.verbose}"></property>   <property name="statistics" value="${jdbc.statistics}"></property>   <property name="statisticsLogLevel" value="${jdbc.statisticsLogLevel}"></property> </bean>   <!--數據源 讀-->   <bean id="dataSourceR" class="org.logicalcobwebs.proxool.ProxoolDataSource">     <property name="alias" value="ihotelR"></property>     <property name="delegateProperties">       <value>user=${jdbc.r.username},password=${jdbc.r.password}       </value>     </property>     <property name="user" value="${jdbc.r.username}" />     <property name="password" value="${jdbc.r.password}" />     <property name="driver" value="${jdbc.r.driverClassName}" />     <property name="driverUrl" value="${jdbc.r.url}" />     <property name="maximumConnectionCount" value="${jdbc.maximumConnectionCount}"></property>     <property name="maximumActiveTime" value="${jdbc.maximumActiveTime}"></property>     <property name="maximumConnectionLifetime" value="${jdbc.maximumConnectionLifetime}"></property>     <property name="prototypeCount" value="${jdbc.prototypeCount}"></property>     <property name="houseKeepingSleepTime" value="${jdbc.houseKeepingSleepTime}"></property>     <property name="simultaneousBuildThrottle" value="${jdbc.simultaneousBuildThrottle}"></property>     <property name="houseKeepingTestSql" value="${jdbc.houseKeepingTestSql}"></property>     <property name="verbose" value="${jdbc.verbose}"></property>     <property name="statistics" value="${jdbc.statistics}"></property>     <property name="statisticsLogLevel" value="${jdbc.statisticsLogLevel}"></property>   </bean>   <!-- 動態數據源 -->   <bean id="dynamicDataSource" class="com.dao.datasource.DynamicDataSource">     <!-- 通過key-value關聯數據源 -->     <property name="targetDataSources">       <map>         <entry value-ref="dataSourceRW" key="dataSourceKeyRW"></entry>         <entry value-ref="dataSourceR" key="dataSourceKeyR"></entry>       </map>     </property>     <property name="defaultTargetDataSource" ref="dataSourceRW" />     </bean> <!--mybatis與Spring整合 開始 --> <bean id="sqlSessionFactory" name="sqlSessionFactory"   class="org.mybatis.spring.SqlSessionFactoryBean">   <property name="configLocation" value="classpath:conf/core/sqlMapConfig.xml" />   <property name="dataSource" ref="dynamicDataSource" /> </bean> 

動態數據源dynamicDataSource中的dataSourceKeyRW、dataSourceKeyR就是

protected abstract Object determineCurrentLookupKey(); 

這個方法要返回的值。那么如何設置,讓這個方法的返回值是根據我們的需要返回dataSourceKeyRW、dataSourceKeyR呢?由于這個方法沒有入參,并且是spring自動調用的,因此考慮使用靜態變量存儲dataSource的key,在調用sql語句前設置靜態變量的值,然后在這個方法中得到靜態變量的值,返回。又考慮到多線程,同時可能會有很多請求,為避免線程之間相互干擾,考慮使用threadLocal。

先看存儲dataSourceKey的容器類。

public class DBContextHolder {   /**    * 線程threadlocal    */   private static ThreadLocal<String> contextHolder = new ThreadLocal<>();   private String DB_TYPE_RW = "dataSourceKeyRW";   private String DB_TYPE_R = "dataSourceKeyR";   public String getDbType() {     String db = contextHolder.get();     if (db == null) {       db = DB_TYPE_RW;// 默認是讀寫庫     }     return db;   }   /**    * 設置本線程的dbtype    * @param str    * @see [相關類/方法](可選)    * @since [產品/模塊版本](可選)    */   public void setDbType(String str) {     contextHolder.set(str);   }   /**    * clearDBType    * @Title: clearDBType    * @Description: 清理連接類型    */   public static void clearDBType() {     contextHolder.remove();   } } 

動態數據源的實現類。

public class DynamicDataSource extends AbstractRoutingDataSource {   /*    * (non-Javadoc)    * @see javax.sql.CommonDataSource#getParentLogger()    */   @Override   public Logger getParentLogger() throws SQLFeatureNotSupportedException {     // TODO Auto-generated method stub     return null;   }   /**    * override determineCurrentLookupKey    * <p>    * Title: determineCurrentLookupKey    * </p>    * <p>    * Description: 自動查找datasource    * </p>    * @return    */   @Override   protected Object determineCurrentLookupKey() {     return DBContextHolder.getDbType();   } } 

在DAO層中設置數據庫類型。

/**    * 添加郵件    * @param sms    * @return    */   public boolean insertEmail(Email email) {     //根據具體需要設置不同的數據庫     DBContextHolder.setDbType(DBContextHolder.DB_TYPE_RW);     //DBContextHolder.setDbType(DBContextHolder.DB_TYPE_R);     int result = this.getSqlSession().insert(STATEMENT + ".addEntity",         email);     return result == 1;   } 

在本例中,我們是在DAO中指定數據庫,我們也可以根據需要在service或者controller中指定DB類型,需要記住的是setDbType是針對線程維度的。要考慮多線程的問題。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 进贤县| 白朗县| 青海省| 寿光市| 北海市| 达州市| 新巴尔虎右旗| 东兴市| 绥滨县| 南阳市| 海原县| 定结县| 镇远县| 河池市| 建始县| 江源县| 韩城市| 株洲市| 柯坪县| 屯留县| 五莲县| 科技| 宿州市| 离岛区| 井陉县| 十堰市| 新竹县| 延安市| 凤凰县| 库尔勒市| 花莲市| 崇左市| 达拉特旗| 扬中市| 新宾| 芷江| 滦平县| 新建县| 海丰县| 潮州市| 荔波县|