日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL数据库读写分离

發布時間:2023/12/14 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL数据库读写分离 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先,設置一個攔截器,攔截數據庫操作,判斷類型,動態選擇數據源
DynamicDataSourceinterceptor.java

package com.mlr.dao.split;import java.util.Locale; import java.util.Properties; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.keygen.SelectKeyGenerator; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.support.TransactionSynchronizationManager;@Intercepts({@Signature(type = Executor.class,method = "update",args={MappedStatement.class,Object.class}),@Signature(type = Executor.class,method = "query",args={MappedStatement.class,Object.class,RowBounds.class, ResultHandler.class})}) public class DynamicDataSourceinterceptor implements Interceptor {private static Logger logger = LoggerFactory.getLogger(DynamicDataSourceinterceptor.class);private static final String REGEX = ".*insert\\u0020.*|.*delete\\0020.*|.*update\\u0020.*";public java.lang.Object intercept(Invocation invocation) throws Throwable {boolean synchronizationActive = TransactionSynchronizationManager.isSynchronizationActive();//對于不是事務管理的操作Object[] objects = invocation.getArgs();String lookupKey = DynamicDataSourceHolder.DB_MASTER;//獲取操作類型MappedStatement mappedStatement = (MappedStatement) objects[0];if (synchronizationActive != true) {if (mappedStatement.getSqlCommandType().equals(SqlCommandType.SELECT)) {if (mappedStatement.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) {lookupKey = DynamicDataSourceHolder.DB_MASTER;} else {BoundSql boundSql = mappedStatement.getSqlSource().getBoundSql(objects[1]);String sql = boundSql.getSql().toLowerCase(Locale.CHINA).replaceAll("[\\t\\n\\r]", "");//符合正則用主庫,不符合用從庫if (sql.matches(REGEX)) {lookupKey = DynamicDataSourceHolder.DB_MASTER;} else {lookupKey = DynamicDataSourceHolder.DB_SLAVE;}}}}//對于事務管理都用主庫else{lookupKey = DynamicDataSourceHolder.DB_MASTER;}logger.debug("設置方法[{}],use[{}]Strategy,SqlCommandType[{}]...",mappedStatement.getId(),lookupKey,mappedStatement.getSqlCommandType().name());DynamicDataSourceHolder.setDBType(lookupKey);return invocation.proceed();}/*** Executor支持增刪改查操作,當操作時候攔截下來判斷用哪個數據源*/public java.lang.Object plugin(java.lang.Object target) {if (target instanceof Executor) {return Plugin.wrap(target, this);} else {return target;}}public void setProperties(Properties properties) {} }

DynamicDataSourceHolder.java

package com.mlr.dao.split;import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class DynamicDataSourceHolder {private static Logger logger = LoggerFactory.getLogger(DynamicDataSourceHolder.class);private static ThreadLocal<String> contextHolder = new ThreadLocal<String>();public static final String DB_MASTER = "master";public static final String DB_SLAVE = "slave";/*** 獲取類型* @return*/public static String getDBType() {String db = contextHolder.get();if (db == null) {db = DB_MASTER;}return db;}/*** 設置連接類型* @param str*/public static void setDBType(String str) {logger.debug("所使用的數據源為" + str);contextHolder.set(str);}/*** 清理連接類型* @param str*/public static void clearDBType(String str) {contextHolder.remove();}}

DynamicDataSource .java

package com.mlr.dao.split;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource{protected Object determineCurrentLookupKey() {return DynamicDataSourceHolder.getDBType();} }

然后配置mybatis-config.xml中添加攔截器

<plugins><plugin interceptor="com.mlr.dao.split.DynamicDataSourceinterceptor"></plugin></plugins>

在spring-dao.xml中配置數據源

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 配置整合mybatis過程 --><!-- 1.配置數據庫相關參數properties的屬性:${url} --><context:property-placeholder location="classpath:jdbc.properties"/><!-- 2.數據庫連接池 --><bean id="abstractDataSource" abstract="true" destroy-method="close"class="com.mchange.v2.c3p0.ComboPooledDataSource"><!-- 配置連接池屬性 --><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><!-- c3p0連接池的私有屬性 --><property name="maxPoolSize" value="30"/><property name="minPoolSize" value="10"/><!-- 關閉連接后不自動commit --><property name="autoCommitOnClose" value="false"/><!-- 獲取連接超時時間 --><property name="checkoutTimeout" value="10000"/><!-- 當獲取連接失敗重試次數 --><property name="acquireRetryAttempts" value="2"/></bean><!--主庫數據源--><bean id="master" parent="abstractDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.master.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--從庫數據源--><bean id="slave" parent="abstractDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.slave.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--配置動態數據源,這里targetDataSource就是路由數據源所對應名稱--><bean id="dynamicDataSource" class="com.mlr.dao.split.DynamicDataSource"><property name="targetDataSources"><map><entry value-ref="master" key="master"></entry><entry key="master" value-ref="master"></entry></map></property> </bean><!--懶加載,程序運行后判斷sql--> <bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"><property name="targetDataSource"><ref bean="dynamicDataSource"></ref></property> </bean><!-- 3.配置SqlSessionFactory對象 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 注入數據庫連接池 --> <property name="dataSource" ref="dataSource"/> <!-- 配置MyBaties全局配置文件:mybatis-config.xml --> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!-- 掃描entity包 使用別名 --> <property name="typeAliasesPackage" value="com.mlr.entity"/> <!-- 掃描sql配置文件:mapper需要的xml文件 --> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean><!-- 4.配置掃描Dao接口包,動態實現Dao接口,注入到spring容器中 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 注入sqlSessionFactory --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!-- 給出需要掃描Dao接口包 --> <property name="basePackage" value="com.mlr.dao"/> </bean></beans>

最近在整理一些資源工具,放在網站分享 http://tools.maqway.com
歡迎關注公眾號:麻雀唯伊 , 不定時更新資源文章,生活優惠,或許有你想看的

總結

以上是生活随笔為你收集整理的MySQL数据库读写分离的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。