免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

SpringBoot+MyBatisPlus多數(shù)據(jù)源動態(tài)切換實(shí)戰(zhàn):MySQL與SqlServer

SpringBoot+MyBatisPlus多數(shù)據(jù)源動態(tài)切換實(shí)戰(zhàn):MySQL與SqlServer 1. 項目背景與多數(shù)據(jù)源需求拆解1.1 為什么一個項目會同時連上 MySQL 和 SqlServer在實(shí)際業(yè)務(wù)里一套服務(wù)對接多個數(shù)據(jù)庫的需求比想象中要普遍。我這次遇到的項目就是一個典型的傳統(tǒng)行業(yè)改造場景老系統(tǒng)跑在 SqlServer 上沉淀了十多年的歷史數(shù)據(jù)包括訂單流水、人員檔案、流程審批記錄這些數(shù)據(jù)不能說丟就丟也不可能短期內(nèi)做完整遷移。而新開發(fā)的業(yè)務(wù)模塊比如用戶畫像、消息推送、數(shù)據(jù)分析報表則更適合放到 MySQL 里畢竟這套技術(shù)棧更輕量生態(tài)也更活躍團(tuán)隊維護(hù)起來成本更低。項目要求很直白同一個 SpringBoot 服務(wù)里既要能查 SqlServer 里的歷史數(shù)據(jù)又要能讀寫 MySQL 里的新業(yè)務(wù)數(shù)據(jù)還得保證切換過程對業(yè)務(wù)代碼盡可能透明。翻譯成技術(shù)語言就是要在 MyBatisPlus 這套 ORM 框架下實(shí)現(xiàn)多數(shù)據(jù)源接入和動態(tài)切換。這里先說明一個容易混淆的概念。多數(shù)據(jù)源和讀寫分離是兩回事。讀寫分離是同一個數(shù)據(jù)庫的主從副本結(jié)構(gòu)完全一致只是分擔(dān)讀寫的壓力。多數(shù)據(jù)源則是多個獨(dú)立的數(shù)據(jù)庫實(shí)例結(jié)構(gòu)可能完全不同甚至數(shù)據(jù)庫類型都不一樣——MySQL 和 SqlServer 在 SQL 語法、分頁方式、數(shù)據(jù)類型上都有差異。本次項目屬于后者難點(diǎn)在于不是簡單配兩個連接池就完事而是要讓上層業(yè)務(wù)代碼在幾乎無感知的情況下完成數(shù)據(jù)源的切換。1.2 方案選型對比分包、AOP切面還是動態(tài)路由多數(shù)據(jù)源的實(shí)現(xiàn)方案業(yè)界主流有幾種我簡單梳理一下方便大家對照自己的場景選型。第一種叫分包方式也是最古老的做法。按照包名區(qū)分 dao 層接口比如com.example.mapper.mysql下的走 MySQL 數(shù)據(jù)源com.example.mapper.sqlserver下的走 SqlServer 數(shù)據(jù)源。每個數(shù)據(jù)源配置獨(dú)立的SqlSessionFactory各管各的包互不干擾。優(yōu)點(diǎn)是實(shí)現(xiàn)簡單、邏輯清晰問題是有多少數(shù)據(jù)源就要配置多少套 MyBatis 環(huán)境代碼一多維護(hù)成本就上來了而且一旦出現(xiàn)跨庫業(yè)務(wù)就得寫多套 Mapper 去拼裝數(shù)據(jù)。第二種是 AOP 自定義注解的方式。核心思路是定義一個DataSource注解標(biāo)注在 Service 或 Mapper 方法上通過切面在方法執(zhí)行前動態(tài)切換數(shù)據(jù)源執(zhí)行完再切回來。這種方式靈活度高可以做到按方法粒度控制數(shù)據(jù)源而且改造量相對小只要在需要切換的方法上加個注解就行。第三種是動態(tài)路由方式基于 Spring 提供的AbstractRoutingDataSource抽象類。它內(nèi)部維護(hù)一個目標(biāo)數(shù)據(jù)源的 Map通過determineCurrentLookupKey()方法動態(tài)決定當(dāng)前線程使用哪個數(shù)據(jù)源。配合 ThreadLocal 存儲數(shù)據(jù)源標(biāo)識就能實(shí)現(xiàn)運(yùn)行時的自由切換。我最終選的是方案二和方案三的結(jié)合基于AbstractRoutingDataSource做底層路由再封裝自定義注解和 AOP 切面做上層控制。這樣既能享受動態(tài)切換的靈活性又能通過注解讓業(yè)務(wù)代碼保持整潔。這也是目前大多數(shù)互聯(lián)網(wǎng)項目的通行做法如果你看過一些開源的多數(shù)據(jù)源框架比如dynamic-datasource-spring-boot-starter底層思路其實(shí)是一樣的。1.3 項目環(huán)境與版本信息做之前先把版本定下來避免后面掉進(jìn)版本兼容的坑里。我這次用的環(huán)境是組件版本JDK1.8SpringBoot2.3.7.RELEASEMyBatisPlus3.4.3.4MySQL5.7SqlServer2012Maven3.6.3這里提醒一句SpringBoot 版本別追太高。我見過有同事直接用 SpringBoot 3.x結(jié)果發(fā)現(xiàn)javax變成了jakarta很多老依賴都跑不起來。如果項目里還有歷史代碼建議先用 2.x 的穩(wěn)定版本把功能跑通。2. 靜態(tài)雙數(shù)據(jù)源配置從零開始接入 MySQL 和 SqlServer2.1 Maven 依賴引入的正確姿勢先把基礎(chǔ)依賴配好。除了 SpringBoot 和 MyBatisPlus 的常規(guī)依賴之外還需要把兩個數(shù)據(jù)庫的驅(qū)動都引進(jìn)來。這里有個容易踩的坑MySQL 驅(qū)動的 groupId 和 artifactId 在不同版本之間有變化mysql:mysql-connector-java是老坐標(biāo)com.mysql:mysql-connector-j是新坐標(biāo)別搞混了。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.4.3.4/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.49/version /dependency dependency groupIdcom.microsoft.sqlserver/groupId artifactIdmssql-jdbc/artifactId version9.4.1.jre8/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependencySqlServer 驅(qū)動的版本選擇有個細(xì)節(jié)。mssql-jdbc的版本號后綴jre8表示支持 Java 8如果你用的 JDK 是 1.8選帶這個后綴的版本最穩(wěn)妥。如果項目用 JDK 11 以上可以選不帶后綴或帶jre11的版本。2.2 application.yml 配置兩個數(shù)據(jù)源的參數(shù)化配置依賴配好后就是寫配置。我習(xí)慣把數(shù)據(jù)源信息放在application.yml里動態(tài)配置這樣不同環(huán)境之間切換只需要改配置文件不用動代碼。spring: datasource: mysql: driver-class-name: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/business_db?useUnicodetruecharacterEncodingutf-8useSSLfalse username: root password: root123 sqlserver: driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc-url: jdbc:sqlserver://192.168.1.100:1433;DatabaseNamehistory_db username: sa password: Sa123456注意這里的 key 是jdbc-url不是url。如果用urlSpringBoot 的自動配置會嘗試把它當(dāng)作默認(rèn)數(shù)據(jù)源來處理導(dǎo)致多數(shù)據(jù)源場景下的配置錯亂。這是我見過很多人踩過的坑寫的時候一定要看清。另外有個小細(xì)節(jié)每套數(shù)據(jù)源的driver-class-name必須明確指定不要依賴 SpringBoot 自動推斷。MySQL 8.0 以上版本驅(qū)動類名變成了com.mysql.cj.jdbc.Driver如果你用的是 8.x 驅(qū)動卻配了舊類名啟動時必報錯。2.3 數(shù)據(jù)源配置類手動裝配 SqlSessionFactory多數(shù)據(jù)源場景下需要手動創(chuàng)建數(shù)據(jù)源和SqlSessionFactory繞開 SpringBoot 的自動配置。這里以 MySQL 數(shù)據(jù)源為例Configuration public class DataSourceConfig { Bean(name mysqlDataSource) ConfigurationProperties(prefix spring.datasource.mysql) public DataSource mysqlDataSource() { return DataSourceBuilder.create().build(); } Bean(name sqlServerDataSource) ConfigurationProperties(prefix spring.datasource.sqlserver) public DataSource sqlServerDataSource() { return DataSourceBuilder.create().build(); } Bean(name dynamicDataSource) public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource new DynamicDataSource(); MapObject, Object dataSourceMap new HashMap(4); dataSourceMap.put(mysql, mysqlDataSource()); dataSourceMap.put(sqlserver, sqlServerDataSource()); dynamicDataSource.setTargetDataSources(dataSourceMap); dynamicDataSource.setDefaultTargetDataSource(mysqlDataSource()); return dynamicDataSource; } Bean(name sqlSessionFactory) public SqlSessionFactory sqlSessionFactory(Qualifier(dynamicDataSource) DataSource dynamicDataSource) throws Exception { MybatisSqlSessionFactoryBean sessionFactory new MybatisSqlSessionFactoryBean(); sessionFactory.setDataSource(dynamicDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(classpath*:mapper/**/*.xml)); return sessionFactory.getObject(); } }這里有幾個關(guān)鍵點(diǎn)。第一MybatisSqlSessionFactoryBean用的是 MyBatisPlus 自帶的類不是 mybatis 原生的SqlSessionFactoryBean這樣才能讓 MyBatisPlus 的分頁插件、邏輯刪除等功能生效。第二mapperLocations用classpath*通配符這樣多個數(shù)據(jù)源的 Mapper XML 文件可以放在不同子目錄下避免路徑?jīng)_突。第三dynamicDataSource作為唯一的數(shù)據(jù)源注入到 MyBatis 里所以最終所有 Mapper 操作的入口都是動態(tài)數(shù)據(jù)源由它在內(nèi)部做轉(zhuǎn)發(fā)。3. 動態(tài)數(shù)據(jù)源實(shí)現(xiàn)核心類與 AOP 自動切換3.1 AbstractRoutingDataSourceSpring 預(yù)留的擴(kuò)展點(diǎn)AbstractRoutingDataSource是 Spring 提供的一個抽象類它的核心作用就是做一個路由分發(fā)。你可以把它理解成一個中轉(zhuǎn)站它自己不是一個真正意義上的數(shù)據(jù)庫連接池而是維護(hù)著一組目標(biāo)數(shù)據(jù)源每次獲取連接的時候通過抽象方法determineCurrentLookupKey()來決定應(yīng)該返回哪個真實(shí)數(shù)據(jù)源的連接。實(shí)現(xiàn)起來很簡單public class DynamicDataSource extends AbstractRoutingDataSource { Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceKey(); } }關(guān)鍵是DataSourceContextHolder通常用 ThreadLocal 實(shí)現(xiàn)public class DataSourceContextHolder { private static final ThreadLocalString CONTEXT new ThreadLocal(); public static void setDataSourceKey(String dataSourceKey) { CONTEXT.set(dataSourceKey); } public static String getDataSourceKey() { return CONTEXT.get(); } public static void clear() { CONTEXT.remove(); } }為什么必須用 ThreadLocal因為 Spring 的DataSourceUtils在獲取連接的時候會先看當(dāng)前事務(wù)上下文里是否已有連接如果有就直接復(fù)用。ThreadLocal 能保證同一線程內(nèi)數(shù)據(jù)源切換在當(dāng)前線程內(nèi)是隔離的不會影響其他線程。但這也引出一個隱患——線程池復(fù)用問題后面我會在踩坑部分詳細(xì)說。3.2 自定義注解 DataSource光有路由還不夠得讓業(yè)務(wù)代碼能方便地指定數(shù)據(jù)源。我定義了一個注解Target({ElementType.METHOD, ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface DataSource { String value() default mysql; }這個注解可以標(biāo)注在 Service 方法上也可以標(biāo)注在類上。標(biāo)注在類上表示整個類的所有方法默認(rèn)走某個數(shù)據(jù)源標(biāo)注在方法上則覆蓋類級別的配置。一個是粗粒度一個是細(xì)粒度兩者結(jié)合使用起來非常靈活。3.3 AOP 切面方法執(zhí)行前自動切換核心切面邏輯如下Aspect Component Order(1) public class DataSourceAspect { Pointcut(annotation(com.example.annotation.DataSource) || within(com.example.annotation.DataSource)) public void dataSourcePointCut() {} Before(dataSourcePointCut()) public void doBefore(JoinPoint joinPoint) { MethodSignature signature (MethodSignature) joinPoint.getSignature(); Method method signature.getMethod(); DataSource dataSource method.getAnnotation(DataSource.class); if (dataSource null) { dataSource joinPoint.getTarget().getClass().getAnnotation(DataSource.class); } if (dataSource ! null) { DataSourceContextHolder.setDataSourceKey(dataSource.value()); } } After(dataSourcePointCut()) public void doAfter(JoinPoint joinPoint) { DataSourceContextHolder.clear(); } }切面的Order(1)很重要。如果項目里同時有事務(wù)切面必須保證數(shù)據(jù)源切面的優(yōu)先級高于事務(wù)切面。原因在于Spring 的事務(wù)管理在開啟事務(wù)時就要確定使用哪個數(shù)據(jù)源如果事務(wù)切面先執(zhí)行它拿到的還是默認(rèn)數(shù)據(jù)源后面的切換就白做了。切面邏輯里有個細(xì)節(jié)within是用來匹配類級別注解的。我的切點(diǎn)同時寫了annotation和within這樣能兼顧方法級和類級的注解配置避免在使用類級注解時切面不生效的問題。4. 實(shí)操踩坑實(shí)錄MyBatisPlus 配合多數(shù)據(jù)源的高頻問題4.1 分頁插件配置問題單頁 500 條限制的真相先說說 MyBatisPlus 分頁的事。很多人在網(wǎng)上搜到MyBatisPlus 單頁 500 條限制其實(shí)這并不是框架硬編碼的限制而是分頁插件配置不到位導(dǎo)致的。老版本的 MyBatisPlus 分頁插件默認(rèn)有l(wèi)imit保護(hù)不配置的話某些版本會限制單頁查詢條數(shù)。正確配置方式是在 MyBatisPlus 的配置類里添加分頁插件Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); PaginationInnerInterceptor paginationInnerInterceptor new PaginationInnerInterceptor(); paginationInnerInterceptor.setMaxLimit(500L); paginationInnerInterceptor.setOverflow(false); interceptor.addInnerInterceptor(paginationInnerInterceptor); return interceptor; } }這里setMaxLimit(500L)就是網(wǎng)上說的單頁 500 限制的源頭。如果不希望限制單頁大小可以把這個值設(shè)大或者不設(shè)置。但我要提醒一句這個限制其實(shí)是好心防止有人寫LIMIT 1000000這種查詢把數(shù)據(jù)庫打掛。生產(chǎn)環(huán)境建議保留只是結(jié)合實(shí)際業(yè)務(wù)把閾值調(diào)到一個合理的值。另外一個更隱蔽的問題是在多數(shù)據(jù)源場景下MySQL 和 SqlServer 的分頁語法不一樣。MySQL 用LIMIT ? OFFSETSqlServer 2012 以上用OFFSET ? ROWS FETCH NEXT ? ROWS ONLY。如果只給 MyBatisPlus 配置了 MySQL 方言的分頁插件切到 SqlServer 后分頁邏輯就會出錯。好在 MyBatisPlus 的PaginationInnerInterceptor是支持多方言的它會根據(jù)當(dāng)前數(shù)據(jù)源的類型自動選擇合適的方言。但這要求你的多個數(shù)據(jù)源必須都注冊到同一個 MyBatis 環(huán)境里而不能拆成多個SqlSessionFactory否則多方言識別就失效了。4.2 關(guān)鍵字沖突表名和字段名的那些坑SqlServer 有一些保留關(guān)鍵字是 MySQL 里可以隨便用的比如order、user、group、index等。我在項目里就碰到過一張 SqlServer 的歷史表字段名叫index在 MySQL 里這個字段名完全合法在 SqlServer 里必須加方括號才能查。MyBatisPlus 提供了全局的關(guān)鍵字自動轉(zhuǎn)義開關(guān)mybatis-plus: global-config: db-config: column-format: %s但這個配置只對 MySQL 的反引號有效。如果同時操作 SqlServer反引號就不認(rèn)了。更穩(wěn)妥的做法是在實(shí)體類的TableField注解上手動指定別名TableField(index) private Integer index;如果是 SqlServer需要寫成TableField([index]) private Integer index;這種問題防不勝防尤其是接手老數(shù)據(jù)庫的時候。我的建議是先用工具連上 SqlServer把涉及的表結(jié)構(gòu)和字段整體瀏覽一遍建一個關(guān)鍵字清單寫 Mapper 的時候?qū)φ罩幚韯e等到運(yùn)行時報錯了再回頭一個個查。4.3 事務(wù)與數(shù)據(jù)源切換的沖突這個坑非常典型。場景是這樣的有一個方法需要先查 SqlServer 的數(shù)據(jù)再做業(yè)務(wù)處理最后寫 MySQL。一開始我直接在方法上加了Transactional然后通過 AOP 切數(shù)據(jù)源結(jié)果發(fā)現(xiàn)第二個操作還是走的老數(shù)據(jù)源。原因一句話說清楚事務(wù)開啟時數(shù)據(jù)源就已經(jīng)固定了。Transactional是在方法進(jìn)入前就通過事務(wù)管理器獲取了連接后續(xù)的數(shù)據(jù)源切換只是在DataSourceContextHolder里改了 ThreadLocal 的值但事務(wù)上下文里持有的連接還是老數(shù)據(jù)源的那個切不過去。解決辦法有這么幾種第一種業(yè)務(wù)允許的情況下把跨數(shù)據(jù)源的操作拆成兩個方法分別加事務(wù)通過調(diào)用另一個 Service 的方法來完成。這是最省事的辦法。第二種使用分布式事務(wù)方案比如 Seata、Atomikos但引入成本較高小項目沒必要。第三種也是最常用的用編程式事務(wù)替代聲明式事務(wù)Autowired private TransactionTemplate transactionTemplate; public void crossDataSourceOperation() { DataSourceContextHolder.setDataSourceKey(sqlserver); Object result queryFromSqlServer(); DataSourceContextHolder.clear(); transactionTemplate.execute(status - { DataSourceContextHolder.setDataSourceKey(mysql); try { insertToMysql(result); return true; } catch (Exception e) { status.setRollbackOnly(); throw e; } finally { DataSourceContextHolder.clear(); } }); }這樣每個數(shù)據(jù)源的操作在自己的事務(wù)模板里管理互不干擾。但跨數(shù)據(jù)源的數(shù)據(jù)一致性就只能靠業(yè)務(wù)補(bǔ)償來保證了這也是多數(shù)據(jù)源方案天然的限制。4.4 連接池配置多個數(shù)據(jù)源各自為戰(zhàn)連接池這塊也容易出問題。默認(rèn)情況下SpringBoot 2.x 會使用 HikariCP 作為連接池。多數(shù)據(jù)源時每個數(shù)據(jù)源應(yīng)該有自己的連接池配置避免共用一個連接池導(dǎo)致連接耗盡。spring: datasource: mysql: hikari: minimum-idle: 5 maximum-pool-size: 20 connection-timeout: 30000 sqlserver: hikari: minimum-idle: 3 maximum-pool-size: 10 connection-timeout: 15000SqlServer 的連接池大小不用配得跟 MySQL 一樣大。因為 SqlServer 在老系統(tǒng)里主要用于查詢歷史數(shù)據(jù)并發(fā)量相對較低配小一點(diǎn)可以節(jié)省資源。同理超時時間也可以設(shè)置短一些避免 SqlServer 響應(yīng)慢的時候拖垮應(yīng)用線程。4.5 SqlServer 排序規(guī)則沖突問題網(wǎng)上有個熱詞是sqlserver cannot resolve the collation conflict翻譯過來就是排序規(guī)則沖突。這個問題出現(xiàn)在 SqlServer 的臨時表關(guān)聯(lián)查詢時如果兩個表的排序規(guī)則比如Chinese_PRC_CI_AS和SQL_Latin1_General_CP1_CI_AS不一致關(guān)聯(lián)查詢會報錯。在多數(shù)據(jù)源場景下如果我們從 MySQL 同步數(shù)據(jù)到 SqlServer再臨時建表去關(guān)聯(lián)歷史表很容易觸發(fā)這個問題。解決辦法是建臨時表時顯式指定排序規(guī)則CREATE TABLE #temp_table ( user_name NVARCHAR(50) COLLATE Chinese_PRC_CI_AS )或者在關(guān)聯(lián)時用COLLATE強(qiáng)制指定SELECT * FROM table_a a INNER JOIN table_b b ON a.name b.name COLLATE Chinese_PRC_CI_AS這個坑可能隱藏得比較深我遇到過因為排序規(guī)則不一致導(dǎo)致的慢查詢排查了很久才發(fā)現(xiàn)是隱式轉(zhuǎn)換導(dǎo)致索引失效。4.6 SqlServer 字符串轉(zhuǎn)數(shù)字多數(shù)據(jù)源下的數(shù)據(jù)類型兼容SqlServer 里把字符串轉(zhuǎn)數(shù)字常用CAST或CONVERTSELECT CAST(123 AS INT) SELECT CONVERT(INT, 123)MySQL 則用CAST(123 AS SIGNED)或者直接123 0。如果項目里有共用 Mapper XML不同數(shù)據(jù)庫的轉(zhuǎn)換語法就得分別寫不能混用。我的做法是把這類數(shù)據(jù)庫相關(guān)的 SQL 拆到各自的 Mapper 里通過數(shù)據(jù)源切換來保證執(zhí)行正確。另外要注意 SqlServer 的CAST轉(zhuǎn)換失敗會直接報錯不像 MySQL 在某些模式下會有寬松處理。生產(chǎn)環(huán)境如果遇到臟數(shù)據(jù)字符串里有空格或特殊字符轉(zhuǎn)換就會炸。建議先用ISNUMERIC判斷一下SELECT CASE WHEN ISNUMERIC(column_name) 1 THEN CAST(column_name AS INT) ELSE 0 END FROM table_name5. 多數(shù)據(jù)源方案驗證與優(yōu)化建議5.1 單元測試怎么寫才靠譜數(shù)據(jù)源切換這種邏輯一定要寫測試驗證不能等上線了再看效果。我用 SpringBootTest 寫了幾組測試用例覆蓋不同場景的切換邏輯。SpringBootTest RunWith(SpringRunner.class) public class DataSourceSwitchTest { Autowired private UserService userService; Test public void testQueryMysqlUser() { User user userService.getUserFromMysql(1L); Assert.assertNotNull(user); } Test public void testQuerySqlServerUser() { User user userService.getUserFromSqlServer(100L); Assert.assertNotNull(user); } Test public void testSwitchBetweenDataSources() { User mysqlUser userService.getUserFromMysql(1L); User sqlServerUser userService.getUserFromSqlServer(100L); Assert.assertNotNull(mysqlUser); Assert.assertNotNull(sqlServerUser); } }注意測試方法的執(zhí)行順序。JUnit 默認(rèn)的方法執(zhí)行順序是不固定的如果測試類里多個方法都在切換數(shù)據(jù)源ThreadLocal 里的值可能在方法結(jié)束后由After清理一般不會互相影響。但如果某些測試并發(fā)執(zhí)行異常可能會出現(xiàn)數(shù)據(jù)源串了的情況。穩(wěn)妥起見每個測試方法都從默認(rèn)狀態(tài)開始不依賴前一個方法的執(zhí)行結(jié)果。5.2 多數(shù)據(jù)源下的性能優(yōu)化多數(shù)據(jù)源不只是配置問題性能同樣要關(guān)注。幾個實(shí)測經(jīng)驗第一連接池參數(shù)要分別調(diào)優(yōu)。MySQL 作為主庫讀寫頻繁最大連接數(shù)可以設(shè)置得高一些SqlServer 作為輔助庫查詢量大但并發(fā)不高連接數(shù)可以少一些。第二跨數(shù)據(jù)源的循環(huán)查詢要避免。比如先查 SqlServer 拿到 1000 條記錄然后再循環(huán)查 MySQL 補(bǔ)充信息這種寫法性能極差。正確做法是把 SqlServer 查出來的 ID 集合一次性傳給 MySQL用IN查詢批量處理。第三如果查詢的數(shù)據(jù)量比較大利用好索引。SqlServer 老表的索引往往不夠優(yōu)化必要時可以創(chuàng)建覆蓋索引來加速常用查詢。但 DDL 操作要謹(jǐn)慎避免高峰期執(zhí)行。5.3 從 MyBatis 到 MyBatisPlus 的兼容保障項目里既有 MyBatis 的 XML 寫法也有 MyBatisPlus 的 Wrapper 寫法。多數(shù)據(jù)源下這兩種寫法都需要保證切換正常。我踩過的一個坑是在某個自定義 SQL 里用了${ew.customSqlSegment}結(jié)果 MyBatisPlus 的多表查詢沒有自動帶上數(shù)據(jù)源切換邏輯導(dǎo)致部分?jǐn)?shù)據(jù)查不到。這個問題的根源在于MyBatisPlus 的 Wrapper 條件構(gòu)造器在生成 SQL 時對IN類型的條件會有數(shù)量限制的優(yōu)化邏輯。對于超過 1000 條的IN查詢MyBatisPlus 會做拆分處理但這個拆分后的 SQL 執(zhí)行順序可能與數(shù)據(jù)源切換順序不一致。解決方案是手動把IN查詢拆分為多個小批次避免單條 SQL 過大。另外如果要在 MyBatisPlus 中使用自定義 SQL 并拼接 Wrapper建議用${ew.customSqlSegment}時注意轉(zhuǎn)義問題尤其是字段名包含關(guān)鍵字時要在注解或 XML 里確認(rèn)最終 SQL 的正確性。6. 常見問題速查表與排查技巧6.1 問題匯總癥狀可能原因解決辦法啟動報DataSource循環(huán)依賴多個數(shù)據(jù)源的 Bean 互相引用用Primary指定主數(shù)據(jù)源或在配置類中通過Qualifier明確注入切換數(shù)據(jù)源不生效AOP 切面沒有攔截到方法確認(rèn)自定義注解是否標(biāo)在 Service 方法上Order(1)是否配置事務(wù)方法內(nèi)切換數(shù)據(jù)源失敗事務(wù)開啟時連接已鎖定拆分方法或使用編程式事務(wù)SqlServer 查詢報錯字段名是保留字用方括號括起來MyBatisPlus 分頁在 SqlServer 下失效方言識別失敗PaginationInnerInterceptor注冊后確認(rèn)多數(shù)據(jù)源共享同一個SqlSessionFactory連接池報Connection is not available連接泄露或配置過小檢查連接池配置用SELECT * FROM sys.dm_exec_connections之類的語句排查6.2 排查思路與調(diào)試技巧多數(shù)據(jù)源問題排查第一步永遠(yuǎn)是確認(rèn)當(dāng)前線程的數(shù)據(jù)源是什么。我一般在DataSourceAspect里加一行日志log.info(switch datasource to{}, dataSource.value());然后觀察日志輸出是否與預(yù)期一致。如果日志顯示已切換但查詢還是走的老庫那問題大概率出在事務(wù)上如果日志都沒打印那就是 AOP 切面沒起作用需要檢查注解位置和 Spring 掃描路徑。第二個技巧是打開 HikariCP 的連接獲取日志通過監(jiān)控連接池的活動情況來判斷數(shù)據(jù)源是否正確。在application.yml里配置logging: level: com.zaxxer.hikari: DEBUG這樣可以看到每次獲取連接來自哪個數(shù)據(jù)源、連接池的活躍數(shù)是多少對定位連接泄露和切換異常都很有幫助。第三個技巧是查看 MyBatis 的執(zhí)行日志。MyBatisPlus 提供了 SQL 輸出日志可以配置輸出 SQL 內(nèi)容確認(rèn)執(zhí)行的 SQL 語句是否符合當(dāng)前數(shù)據(jù)源的方言。如果 SQL 語法是 MySQL 的但執(zhí)行到了 SqlServer 上基本可以斷定是數(shù)據(jù)源切換出了問題。6.3 后續(xù)擴(kuò)展動態(tài)加數(shù)據(jù)源、分布式事務(wù)如果項目后續(xù)要接入更多數(shù)據(jù)源比如再加一個 PostgreSQL只需要在DataSourceConfig中添加一個新的數(shù)據(jù)源 Bean然后在dynamicDataSource中把它put進(jìn)targetDataSources即可。但要注意如果數(shù)據(jù)源是運(yùn)行時動態(tài)增加的比如多租戶場景需要調(diào)用AbstractRoutingDataSource的afterPropertiesSet()方法來刷新配置。分布式事務(wù)是個更深的話題。如果業(yè)務(wù)上真的需要跨庫的強(qiáng)一致性比如一個操作既要寫 MySQL 又要寫 SqlServer多數(shù)據(jù)源方案已經(jīng)解決不了問題了得引入分布式事務(wù)中間件。我的建議是盡早評估業(yè)務(wù)場景如果只是簡單的查詢和異步補(bǔ)償多數(shù)據(jù)源方案完全夠用如果要做強(qiáng)一致的跨庫寫操作提前設(shè)計好技術(shù)選型不要等寫完了再返工。我在實(shí)際項目中的體會是多數(shù)據(jù)源本身并不復(fù)雜復(fù)雜的永遠(yuǎn)是業(yè)務(wù)邊界和異常處理。動手之前先想清楚哪個庫是主、哪個庫是輔在代碼層面規(guī)定好數(shù)據(jù)源的使用規(guī)范比什么花哨的框架都重要。最后再分享一個平時容易忽略的小細(xì)節(jié)如果你的項目在部署時切換了環(huán)境記得檢查數(shù)據(jù)庫連接串和賬號權(quán)限我遇到過多次因為新環(huán)境 SqlServer 登錄賬號缺少VIEW SERVER STATE權(quán)限導(dǎo)致連接池初始化異常的案例這類問題一般不報錯清楚排查起來比較費(fèi)勁提前做好環(huán)境檢查能省不少事。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
欧美婷婷丁香社区在线播放| 色五月丁香激情| 日本久久综合| 婷婷久久丁香| 五月丁香亚洲婷婷| 天天爽天天爽夜夜爽| 97爱综合| 情色五月天 网站| 日本五月视频| 99热这里只有精品3| 丁香五月天堂网AV| 色噜噜狠狠色综合成人网| 激情色中文| 狠狠爱婷婷五月天| 琪琪色五月婷婷老师| 久久六月天| 天天擼久久擼在线| 久久这里只有精品07| 精品国产a| 99∨VTV| 色播五月婷婷| 色欲一区二区三区精品A片| 五月天婷婷久久日| 色情五月丁香婷婷网| 超碰97久久| 激情五月婷婷视频| 大香蕉综合视频在线| 五月天激情小说| 婷婷香五月天| 婷婷五月天在线综合| 人人爽天天莫| 婷婷丁香视频在线观看免费| 五月婷婷六月丁香免费| 五月丁香六月在线欧美| 色一区高清| 91九色熟女| 97婷婷久久丁香| BBWCUCKOLD精品熟妇| 亚洲AV日韩无码| 亚洲婷婷免费| 五月婷婷影院| 日韩成人AV在线播放| 婷婷色五月在线视频| 丁香伊人激情| 五月色婷婷AV| 99爱无码| 中文字幕 中文字幕明步| 9九九久久精品无码专区| 天天日天天插| 天天爽天天爽| 懂色av粉嫩AV蜜臀AV| 精品一二三区久久AAA片| 欧美影院婷婷| 亚洲精品亚洲人成人网| 熟妇人妻中文字幕无码老熟妇 | 夜夜爽77777妓女免费下载| 开心五月综合激情网| 丁香五月天婷婷激情| 99久久久| 成人网址在线观看| 日日夜夜天天综合| 五月丁香在线| 婷婷不卡基地| 9热视频在线观看| 色久女| 五月婷色色| 99操视频| 九九视频精品在线免费| 国产三级秋霞| 久久ww| 婷婷爱五月天| 婷婷伊人五月天| 天天日人人| 天天射夜夜爽| 婷婷丁香五月天狠狠| 天天久久综合| 天天草天天爽| 亚洲国产精品SUV| 欧美日韩二区在线| 婷婷六月综合| 中文字幕丰满乱孑伦无码专区| 丁香婷婷人妻| 久久视频在线| 9久精品视频| 亚洲五月天婷婷| 最近中文字幕大全免费版在线| 日本欧美成人片AAAA| 色五月婷婷777| av免费在线观看0| 99久热精品在线| 久久婷婷啪啪视频| 六月丁香好婷婷| 丁香婷婷月| 99碰超| 亚洲国产精品VA在线看黑人| 色婷婷激情五月天| 五月丁香婷婷国产精品综合| 激情五月婷婷视频一区二区三区| 国产激情久久久| 拍色综合| 噜噜综合网| 人人噜天天上| 91一起操| 色热久| 婷婷五月天天| 天堂久久精品| 97超碰在线观看免费| 伦乱天堂| 五月婷婷天天| 色五月 婷婷, 大香蕉| 五月婷婷激情日本| 丁香婷婷十月| 丁香六月综合激情| 天堂中文国产| 天天爽天天摸天天爱| 日韩欧美一级大黄网站| 99re这里只有精品视频了| 日本爆乳片手机在线播放| 99热这里| 久久婷婷色综合| 色综合久久天天综合网| 97人人射| 91人碰| 人人舔人人色人人高潮| 999热在线视频| 搡BBBB搡BBB搡18| 久久大香蕉伊人| caopeng超碰| 五月婷婷激情综合网 | 视频这里只有精品16| 七七色色综合| 九月大香蕉| 丁香婷婷激情五月| 精品人妻一区| 激情五月天丁香| 亚洲色色香蕉| 欧美天堂婷婷日韩| 五月婷婷六月爱| 日本激情91| 岛囯综合激情网| 国产亚洲色婷婷99精品| 色情五月丁香| 五月婷婷激情| 超碰免费大香蕉| av人人操| 色色色色色色色色色色色色色色,网站| 国产午夜一区二区三区| 99热老司机| 99热.com| 玖玖热99| 天天干狠狠| 在线理论片| 97人人射| 五月丁香亭亭| 青青夜夜狠狠夜夜狠狠| 久久伊人五月天| 婷婷射综合| 日屌日日操日日色| 91jiuseshunv| 久久精品只有这| 色欲五月婷婷| 欧美日韩成人在线| 色婷婷成人影片| 亚洲天堂色色| 日韩黄黄| 五月丁香婷婷钟和色图| 国产婷婷五月天| 国产成人精品一区二三区熟女在线| 日韩性视频| 99热这里只有精品8| 婷婷五月欧美| 丁香五月婷婷网| 91人人妻人人操人人爽| 综合激情视频| 激情久久肏屄视频| 五月丁香婷婷欧美| 婷婷五月天com| 国产高潮A片羞羞视频涩涩| 精热在线综合网| 五月婷婷丁香在线| 色欲日日躁| 亚洲国产精品二二三三区| 青青日韩| 久久久香| 婷婷五月四狠狠| 五月丁香六月婷婷网| 9999久久久久| 日本强伦片中文字幕免费看| 五月天六月婷| 九九精品综合| 日韩精品AV一区二区三区| 思思热在线视频观看精品| 欧美色五月| 思思视频这里是精品| 97人人干| 丁香网五月天激情| 午夜成人网站在线观看| www.色婷婷.com| 亚洲欧洲中文日韩久久AV乱码| 99这里只有免费的小视频在线观看| 亚洲综合五月天| 成人视频九九| 性爱七区| 99在线精品视频在线观看| 区区久久妻| 97av在线视频| 夜夜撸夜夜骑| 五月丁香六月婷婷,婷| AA片在线观看视频在线播放| 99热6色| 五月天婷综合| 国产精品人人做人人爽人人添| 色五月丁香一区在线| 大香蕉AV电影在线| 婷婷久久大香蕉| 亚洲欧洲色色| 视频一二区| 26UUU精品一区二区| 色婷婷婷综合五月天| 久久XX日本综合| 久久丁香综合| 久久有码| 玖玖综合色| 97精品人人A片免费看| 丁香六月婷婷综合啪啪| 五月丁香色婷婷伊人| 色欲五月丁香| 色色a| 亚洲第一精品网站| 婷婷五月天天天日日夜夜| 色无婷婷| 激情小说五月天| 丁香五月a| 另类图片色五月| 日韩AV中文在线观看| 九九热最新| 久久五月人人摸| 日韩AV中文字幕在线| 色9999日韩国产| 日韩精品色| 一级二级色大片| 国产精品久久久久久久久久| 91天天操天天干天天射| 亚洲热久久| 99久久久国产大片区| 伊人五月天久久| 九九色精品| 丁香婷婷五月天在线视频| WWW.激情| 婷婷在线视频| 五月丁香久人妻中文| 九九色情网站| 成人精品视频99在线观看免费| 91久久色| 夜夜骑夜夜撸| 六月丁香激情婷婷| 色婷婷色五月丁香| 5月色婷婷| 日韩色久| 99视频九九热| 26uuu偷拍亚洲欧洲综合| 国产真人做爰视频免费| 99无码精品| 九色91视频| 综合激情站| 狠狠色丁香婷婷基地| 五月婷婷激情| 九九九热精品| 高清不卡一区| 天天搡日日搡aaaaⅩ| 中文字幕在线不卡视频| 天天操天天插天天射| 少妇出轨做爰高潮A片| 婷婷色婷婷| 99∨VTV| 色婷婷五月天天天干天天操天天爽 | 97日本在线| 六月婷综合| 五月激情啪啪| 亚洲国产精品二二三三区| 一级性爱视频| 久久人人妻| 五月丁香婷婷综合久久| 色综合丁香| 激情丁香五月| www.99日本| 五月在线| 亚洲最大在线| 99久视频| 丰满女老板BD高清A片| 综合网五月| 五月停亭六月,六月停亭的英语 | 国产肥白大熟妇BBBB视频| 精品无码久久久久久久久| 激情五月久久| 丰满少妇猛烈A片免费看观看| 日韩成人综合网| 成人电影一区| 女人高潮内射99精品| 91久久久久久久久18| 激情婷婷五月| 欧美性猛交99久久久久99按摩| 九九Av| 色婷婷影院| www.婷婷五月天| 亚洲国产精品SUV| 亚洲精品又粗又大又爽A片| 成人视频网| 成人免费120分钟啪啪| 五月丁香综合| 老司机视频lsj爱就色| 4399精品一区二区| 五月婷婷激情性爱| 五月天激情站| 丁香五月精品| 自拍偷窥99热| 色婷婷成人做爰A片免费看网站| 风流少妇A片一区二区蜜桃| 人妻丰满精品一区二区A片| 碰97 久| 啪啪视频99| 婷婷久久在线| 天天做天天爱天天日| 五月丁香婷婷成人伊人网| 五月丁香亭亭天天舔| 五月色天情| 91九色无码日韩| 91成人性爱视频| 色伦专区97中文字幕| yw国产AV| 91九色丨国产丨爆乳| 天天日日人| 日日操日日射| 色综合久久天天综合网| 超碰免费成人网站| 99九九热在线观看| 九九婷婷五月天影视| 色噜噜狠狠插综合| 欧美色婷婷| 亚洲黄色网址| 激情婷婷色色| 五月天影院| 99精品自拍视频| 亚洲日韩乱码一区二区三区四区| 99噜噜噜| 韩日另类| 久热天堂| 日本色婷婷五月天成人电影| 激情综合网五月婷婷| 婷婷综合| 丁香婷婷五月人体| 天堂五月婷婷| 色久九| 在线18av | 99热销国产这里有精品| 爱婷婷久久视频| 九九亚洲综合| 色播激情婷婷| 婷婷丁香成人在线视频| 亚洲黄色精品| 色色97丁香婷婷五月天| 五月婷婷激情四季| 日本色婷婷| 伊人综合网站| 色玖玖| 婷婷婷婷色| 综合久| www.sebowuyue| 综合五月天天天天天五月| 噜噜操操| 色婷婷综合在线| 91精品电影18T| 67194中文字幕| 在线看AV| 在线色五月婷婷| 99热e| 超碰A V在线| 丁香五月另类小说在线阅读| 亚洲av骚货| 日韩无码性爱| 直接看的AV网站| 99综合视频一体| 神马欧美精| 色综合色色色色色| 97日韩无套内| 人色五月天婷婷| av大香蕉| 亚洲美女高潮久久久久久69| 欧美色97| 性热视频99精品| 亚洲色婷婷视频| 开心婷婷五月激情网小说| 综合XX网| 在线观看av网站| 可以看的AV网站| 国产99久| 99久久久| 99天堂网最新| www.色婷婷.com| 97婷婷五月丁香| 色情播放| 琪琪色网在线| 开心五月天激情网站| 1024国产在线| 五月综合六月婷婷| 99久久久精品| 很很干天天干| 色九九九九| 狠狠人人婷婷| 日本九九视频| 九九久久综合| 综合五月草| 激情www| 激情五月天丁香| 91综合在线| 婷婷91| 婷婷金品综合视频| 丁香激情五月综合网| 综合色播| 欧美性丁香色色五月天综合爱爱| 亚洲精品久久久久久久久久飞鱼 | 日本九九热| 夜夜爽77777妓女免费下载| 深爱五月激情综合| 在线看片h站| 国产熟女日日骚五月丁香爱| 欧美人人草草| 亚洲美女高潮久久久久久69| 丁香六月婷婷高清| 婷婷五月色激情欧美激情| 久久婷婷五月综合一| 老司机伊人| 亚洲爱婷婷| 天天日天天操心| 五月天激情久久| 久久久中文| 青青草a在线| 日韩AV免费电影在线播放| 天天爽综合| 97婷婷五月激情六月丁香伊人| 中文av网| 成人天天爽| 一本色综合色| 99色| 五月丁香六月婷婷综合免| 69凹凸成人综合网| 综合色影院| 五月丁香六月综合情在线观看| 国产av天堂| 丁香五月婷婷综合网| 婷婷五月18永久免费网站| 色综合久久44| 亚洲五月天伊人| 九九九九无码| 99精品无码| 青青草六月丁香| 99视频在线啪| 双性美人被调教到喷水A片| 激情网婷婷婷| 久久九九爽| 嫩BBB搡BBBB榛BBBB| 26UUU欧美| 五月丁香久久网| 99精品偷自拍| 大香蕉五月婷婷| 五月丁香综合伦理片| 中文在线视频久9| 人妻中文在线| 亭亭五月色男人| 99操碰| 91人久| 99九九玖玖| 亚洲午夜AV| 婷婷娱乐丁香综合网| 91成人看片| 日本不卡一区二区三区| www.婷婷五月天| 五月花婷婷最新| 五月丁香婷草| 亚洲免费成人电影AV| 色综合网址| 黄色笑话深爱激情网丁香五月婷婷啪啪啪啪啪 | 丁香婷婷大香蕉| 丁香五月狠狠在线观看| 中文av网站| 丁香激情五月少妇| 激情伍月 欧美| 国产日韩av片| 奇米四色五月天| 久久小视频| 人人干av| 激情五月天色婷婷| 五月婷婷伊人网| 九色91美女| 99久久五月婷婷| 成人做爰A片免费看网站找不到了| 99热激情| 丁香五月六月婷婷殴美综合| 日 日干 日日做| 亚洲中文字幕av| 五月天怕怕| 蜜乳av一级av| 欧美丰满熟妇BBB久久久| 色婷婷中文在线| 色五月第四色| 美国天天日天天操| 色婷婷国色天香综合| 婷婷在线精品| 99久在线观看| 久久久久激情网| 色婷婷四虎| 久久综合久色欧美综合狠狠| 九九热精品视频在线观看| 大香蕉99热| 精品人妻久久久久久| 五月天黄色激情小说| 五月婷婷开心色伊人| 久久视频婷婷视频| 日本三级韩三级99久久| 久久婷婷啪啪视频| 久99视频在线观看| 91超碰在线观看| 伊人综合色干| 久99热在线观看| 六月激情丁香一道本7777| 久久久全国免费视频| 久久99热精品a片在线观看| 婷婷激情五月天7| 影音先锋按摩| 97色色-99久久| 国产日产成人亚洲欧美国产VA| 五月天激情久久| 亚洲色图81p| 91视频综合网| 97人人操人人| 91狠狠色丁香婷婷综合久久精品| 91丨九色丨国产打屁股| 激情五月天婷婷直播| 色色婷婷五月天| 五月婷婷综合网| 秋霞电影一级黄| 操人妻90p| 欧美五月丁香在线观看| 色射婷婷五月天| 五月天激情网页| 色色色色色爱| 五月丁香色综合| 欧美日韩成人免费在线| 99热国产这里只有精品| 99热这里有精品| 熟女色色一区二区| 九九人人看| 97在线精品视频| 国产韩日亚洲美州欧亚综合在线| 综合色天天| 色婷婷激情视频| 99无吗| 色婷婷先锋| 丁香五月天激情| 免费观看18视频网站| 成人综合视频网址| 香蕉伊人综合| 国产99美少妇| 激情六月一二| 久久伊人婷婷| 国产精产国品一二三在观看| 国产成人亚洲综合亚洲| 亚洲高清在线| 婷婷激情丁五月| 久久538| 五月激情视频| 狠狠婷婷综合| 97干免费视频| 俺去也在线官网| 亚洲综合99| 狠狠爱综合网| 九九九九热99超碰| 成人短视频在线| 五月www| 五月婷婷天天| 久久婷婷色| 婷婷.com| 婷婷操逼| 79精品视频| 亚洲不卡| 啪啪啪丁香五月| 五月婷婷色情| 色婷婷五月天不卡| 五月丁香激情综合网| 亚洲AV久久久久久久久久久久久久久久 | 天天拍久久| 九九热视频在线观看| 婷婷激情五月综合| 久久婷婷东京热| 久色视频首页| 日本操碰碰| 精品二区| 99激情网| WWW.久久久久久久| 99热国产国产| 99热e| 校园春色亚洲色| 亚洲无码播放| 综合五月天婷婷色| 99色婷婷| 日韩黄色AV无码| 天天在线久久综合| 亚洲旡码| 狠爱婷色| 丁香亚洲婷婷五月| 亚洲这里只有精品| 日本三日本三级少妇三级66| 色婷婷中文字母五月丁香| 激情五月天偷拍综合网| XX色综合| 丁香五月综合高清在线| 婷婷狠狠操| 亚洲视频一区| 五月婷婷xxx| 亚洲色五月婷婷| 影音先锋自拍网| 亚洲精品99| 思思热在线播放| 乱精品一区字幕二区| 色婷婷久久综合| 天天操天天操天天操天天操天天操天天操天天操天天操天天操 | 亚洲AV第二区国产精品| 色婷綜合网| 丁香五月婷婷影院| 久久一品区| 欧洲第一久色| 9久热精品在线视频| 五月丁香啪啪激情| 99综合自拍| 97人人操人人拍| 天天干天天 亚洲| 79精品视频在线观看,| 欧美亚洲成人在线| 色婷婷五月天激情在线观看| 丁香五月婷婷激情四射深爱激情| 婷婷五月天无码熟女| 久久综合干| 91色逼| 天天舔天天摸| 综合色视频| 天天操屄网| 国产午夜精品一区二区三区四区| 日韩三级片一区二区| 婷婷精品在线| 激情AV在线| 九热视频在线精品15| 亚洲另类AV| 婷婷丁香人妻天天爽| 久99久视频精品| 天天透天天摸天天舔| 精品影院| 色综合五月婷婷狠狠干| 久久黄色片| 欧美综合丁香网| 亚洲精品无AMM毛片| www.91.com处女在线直播| 五月丁香六月激情综合| 女人露出p毛视频www网站| 日本久久综合| 久热这里只有精品6| 99热青青草| 大香蕉精品视频| 97碰久久| 亚洲五月天婷婷在线| 五他月天啪啪啪| 五月婷六月| 极品另类| 五月丁香六月婷综合成人综合| 超碰成人免费| 国产激情视频在线观看| 日韩五月婷婷| 碰碰人人人| 丁香五月开心五月激情| 伊人久久大香天蕉亚洲特级| 色色五月天婷婷丁香| 丁香五月天黄色片| 日韩视频99| 67194成I人在线观看线路1| 亚州色色色| 五月婷婷六月丁香激情深爱| 最新无毒无码AV| 欧美成人精品一区二区 | 五月婷婷婷综合网| 色婷婷丁香五月天| 色狠狠六月| 日本久久九| 六月婷婷视频| 人妻自慰在线| 五月婷婷综合在线亚洲视频| 综合图片色色| 丁香五月婷婷啪啪| 以及AA大片看看| 五月天播播中文字幕| 97视频久久| 强辱丰满人妻HD中文字幕| 五月婷婷婷自由综合| 久久人人九| 超碰91在线| 噜噜精品| 超碰99在线| 色99久草在线| 五月婷婷久久久| 深爱激情五月天婷婷网| 青青草原伊人网| 这里只有精品无码| 激情欧美婷五月| 偷偷操九九| 天天天干夜夜夜操| 亚洲最大五月六月丁香婷婷| 人妻久久久久| 97luluse| 激情五月天视频| 激情五月婷婷六月丁香| 色婷婷狠狠干| 婷婷激情四射五月天| 婷婷丁香亚洲色综合91| 五月天激情婷婷五月天久久| 99热在线资源| 婷婷综合丁香| 中文字幕成人| 五月婷婷在线视频观看| 视色网在线播放| 91九色 婷婷| 成人中文网| 色色五月天激情| 五月婷婷福利| 99久久66| 六月丁香综合| 五月丁香狠狠爱婷婷综合| 久久九九99| 亭亭玉月丁香| 激情五月丁香激情综合网 | 狠狠干.com| 香蕉综合网| www.五月.com| 天天日夜夜草进麻麻的子宫| 天天久久66xxx| 日韩美一级毛卡片| 色综合久久久无码中文字幕999| 日韩精品999| 人人射人人高潮| 色婷婷婷综合五月天| 色色色色色色色色五月先| av操B网站| 人妻体体内射精一区二区| 久热 91| 99re6久热只有精品6在线直播| 激情综合网,五月| 五月花综合| 99干99| 97色视频网| 亚洲视频在线网站| 日本欧美成人片AAAA| 日日夜夜天天综合| 26.uuu丁香五月婷婷| 另类激情中文| 五月丁香婷婷激情澎湃四射| 五月开心婷婷| 久久综合网免费视频| 99熟女| 123草逼网| 九九综合网色全集 | 思思热在线视频精品| 97色色综合| 久草大| 五月丁香激情欧洲啪啪| 91小黄书网址在线观看| 五月天成人在线视频丁香| 超碰三级秋霞| 俺也去在线久久精品23欧美综合视频网站,丰满人妻一区二区三区在线视频53,丰满 | 久久99婷婷| 五月天操逼网| 99日精品视频| 大香蕉五月天婷婷丁香91| 日本97久久久精品| 91chinese 在线| 男人視頻站| 色玖玖玖| 亭亭玉月丁香| 婷婷射图| 五月丁香福利| 538午夜激情| 91蜜桃婷婷狠狠久久综合9色| 色婷婷www| 亚洲另类在线观看| 亚洲五月天色| 婷婷五月天直播| 色五月婷婷丁香国产在线| 九九视频这里只有精品在线播放| 丁香婷婷六月激情文学 | 日曰躁夜夜躁2026| 超碰操日| 丁香五月97视频| 小泽玛利亚视频一区二区| www91精品| 9色免费网| 91精品人妻少妇无码影院| 久久久999精品| 婷婷色婷婷亚洲成人| 色五月丁香总合网| 午夜丁香六月婷| www婷婷色情网| 激情五月,深深爱五月| 五月婷无码| 色五月天本日| 婷婷激情五月天小说| 激情小说婷婷| 黄色三级日本| 涩五月婷婷| 婷久久久| 97五月婷婷| 九九99在线观看视频| 加勒比色色| 九九婷婷五月天| 91青娱乐青青草| 成人无码精品1区2区3区免费看| 欧洲电影在线观看免费版英语版| 五月综合激情图片| 操97免费超级视频| 久久er+| 丁香五月,激情五月,深爱五月| 五月丁香五月综合欧美| 久月婷婷| 婷婷丁香九色| 在线观看亚洲AV| 丁香色六月婷婷| 激情丁香五月婷婷啪啪| www.婷婷六月天| 色色色网站| 久热伊人在91| 色综合网上班开心婷婷久久| www.夜夜騎夜夜狠| 九九re精品视频在线观看| 五月天激情小说| 久热爱大香蕉在线蜜臀悦色| 婷婷五月天成人在线视频| 99热这里只有精品69| 99亚洲视频| 思思热精品在线视频| 激情婷婷激情在线不卡| 成人噜噜网| 操逼棍操逼| 激情深爱五月天| 中文AⅤ大全| 婷婷六月丁香开心深深爱| 婷婷五亚洲| 九九精品免费| 日本99婷婷| 5月丁香婷婷| 开心激情婷婷| 大香蕉在九| 久久九区| 色综合激情| 亚洲欧洲另类| 一区视频网站| 天天草天天日| 天天操天天插| 亚洲人人操| 天天爽综合| 五月婷婷亚洲色视频| 日本强伦片中文字幕免费看| 我爱大香蕉| 婷婷亚洲欧美丁香五月| 日韩中文字幕| 无码啪啪| 丁香六月婷婷综合| 97在线观视频免费观看| 五月天婷婷xxx| 日韩啊啊啊| 在线超碰免费| 婷婷丁香五月激情综合站_久久五月丁香激情综合_开心五月综合激情综合五月_婷 | 天天综合干| 99色干| 999九九九久久久99HD| 一区二区中文字幕| 色色五月天激情| 亚洲天堂有码| 五月丁香狠狠| 欧美性生交XXXXX无码小说| 日本三级韩三级99久久| 先锋资源91| 99热伊人综合| 人人看人人要| 国产亚洲精品AAAAAAA片| 色色色激情| 五月婷婷综合网| 五月丁香婷色| 日本 @ va 免费| 色级停停| www.五月激情.com| 天天射影院| 婷婷综合| 婷婷五月色天| 激情五月综合色| 色婷| 亚洲旡码| 狼人婷婷久久| 国产免费一区二区三区三州老师F1F1.CC | 亚洲天堂色色| 色五月开心久久网| 婷婷五月色情天| 激情综合网婷婷五夜| 五月天婷婷久久综合| 丁香啪啪| 成人久久天天x资源站| 亚洲国产99| 五月丁香亚洲校园欧美| 六月丁香激情网| 7超碰自拍| 丁香色婷婷| 日韩在线9| 婷婷视频网| 六月婷婷激情图片| 能直接看的av网站| 狠狠搞五月天| 婷婷综合五月| 综合激情五月丁香9999久久精| 亚洲激情网| 丁香五月98| 午夜69成人做爰视频| 日逼免费视频| 另类丁香五月天区图| 国产精品热搜丁香五月婷婷| 国内精品99| 5月丁香综合网| 亚洲亚洲人成综合网络| 五月婷婷久久网| 亚洲AV成人无码精品| 天天情色综合网| 色婷婷丁香社综合| 色综合久久88色综合天天99| 婷婷的99视频网站| 中文字幕在线日亚州9| 99热6这里只有精品6| 免费超碰在线观看| 97五月天婷婷| 国产一区18| 色五月av| AV在线大香蕉| 99热这里是精品| 伊人国产婷婷五月天| 丁香五月天婷婷激情| 婷婷伊人綜合| 日本一级一级一级一级| 婷婷久久免费| 婷婷在线播放| 久久精品视频9| www.97干视频| 九九视频在线| 婷婷五月天伊人网在线观看视频| 婷婷五月娱乐在线| 久久精品99久久久久久| 婷婷五月丁香六月伊人网| 综合六月久久| 五月天播播中文字幕 | 610018岁成人视频| 五月亭亭性| 色情综合网| 亚洲亚洲人成综合网络| 五月丁香六月色| av第一二区| www.五月天| 五月天激情无码专区| 性爱五月丁香| 成熟妇人A片免费看网站 | 激情综合网之激情五月| 亚洲不卡123| 99热国产精品| 久久99美女精彩视频| 大香线蕉伊人| 思思久久99热只有频精品66| AV人人操| 狠狠色性| 精品久久99| 天天综合永久| 中文字幕AV在线| 国产亚洲精品久久久久久久久动漫| 激情深爱五月天| 丁香五月大片| 91日视频| www.seqingwuyuetian| 极品另类| 综合五月激情| 久久五月婷婷视频| 色色综合网站| 天天插天天插| 精品无码人妻一区| 99在线观看视频| 久机视频这只有精品| 色婷婷丁香六月| 精品人妻在线| 国产一级片色色| 色色婷| 99热免| 男人综合网| 亚洲av免费在线| www.久99| 97色色网| 丁香九月综合激情| 五月丁香在线综合| VA国产在线综合网站| 色播五月天婷婷老师| 亚洲av另类在线观看| 婷婷深爱五月| 天天操中文字幕| 婷婷五月天黄色小说| 色综合色综合婷婷热| 色狠狠999综合| 麻豆忘忧草午夜| 国产亚洲成AV人片在线观黄桃| 99九九在线精品热动漫| 韩国三级五月天婷婷。| 人人干天天操五月丁香| 激情久久久久久| 五月婷婷六月综合| 亚洲人成网站999综合| 色五月综合网| 狠狠综合| 99在线精品视频| 99综合色| 99成人免费热视频| 婷婷六月网| 久久99最新| www.婷婷五月天.com| 婷丁香五月天| 六月婷婷AV| 五月精品99综合| 色色色色欧美| 九九久久精品| 久久99网站| 色婷婷五月综合| 九九色图| 九九99精品| 婷婷五月电影| 丁香婷婷激情| 久热这里| 五月天亭亭俺也| 色婷婷五月在线| 综合久久五月天| 夜夜爽天天日| 99爱无码| AV天堂婷婷五月天| 国产资源91在线| 五月丁香花婷婷玉莉AV| 米奇影视资源婷婷狠狠色激情欧美五月丁香 | 激情五月天综合网| 色五月AV| 丁香五月激情综合| 另类小说色婷婷| 丁香九月激情| 免费观看欧美成人AA片爱我多深| 婷婷五月成人有| 深夜男女福利刺激影院一区| 五月丁香久久婷| 色婷婷久久视屏| 色天使色婷婷| 啪啪黄页网| 婷婷天堂综合| 天天日天天插天天操| 婷婷丁香五月天婷婷| 久久五月视频| 五月婷婷激情综合| 久久五月天大美女| 五月丁香狠狠爱婷婷综合| 日韩激情婷婷五月天| 2w在线视频| 99在线精品视频在线观看| 婷婷伊人网| 亚洲AV中文在线| 丁香婷婷五月| 久久香蕉影院| 91无码一区人妻A片蜜| 99综合五月免费视频色婷婷| 婷婷五月欧美AA片免费| 色婷婷偷拍| 黄网在线播放| 婷婷五月天,影院| 99小视频网站| 激情深爱五月天| 一起草av| 成人无码髙潮喷水A片| 人人爽网| 在线91日韩| www,色婷婷| 五月婷婷与六月丁香图片激情| 99在线视频精品| 成人性爱无码| 啪啪激情综合| 亚洲亚洲人成综合网络| 日韩人妻AV在线| 九色PORNY在线精品酒店| 国产99久久久| ...婷婷国产成人亚洲日韩| 天天爽日日爽夜夜爽| 狼人狠狠操| 色五月综合| 国产精品涩涩涩视频网站| 亚洲无码影音| 五月花激情网| 91精品综合久久久久久五月丁香| 激情五月天综合图片小说网站| 婷婷五月丁香六月天亚洲综合| 欧洲色色| 色五月丁香五月| 婷婷狠狠综合网入口| 蜜乳人妻一区二区三区| 99re热视频这里只有综合亚洲| 丁香五月天在线直播观看| 激情综合色播| 久久婷五月天| 曰韩五月丁香色婷婷无码| 日本精品干| 色五月天天| 婷婷色在线视频| 涩五月婷婷| 久久综合影院| 久久久婷婷五月天| 国产操B视频| 97色伦另类图片小说视频 | 人妻在线观看视频| 超碰免费99| 区区欧美你爱| www.99视频| 欧美天堂婷婷日韩| 99在线观看| 激情五月丁香六月| 99这里| 婷婷久久伊人| 人人操A| 欧美在线视频免费播放| 丁香婷婷射| 婷婷五月综合色拍| 婷婷激情五月天网站| 永久精品| 天堂无码人妻精品AV一区| 99日在线观看视频| 内射激情在线| 大香蕉九九| 岛囯综合激情网| 婷婷色色五月| 五月婷婷丁香狠狠撸久久| 99热青青草| 亚洲网站999| 色狠狠999综合| 九九热AV| 五月丁香成人网| 99热这里只有精品268| www.色婷婷.com| 五月婷婷六月丁香综合视频在线| 日韩草草草草草草草草草草草草| 久久丝丝热| 男女99免费视频| 五月丁香久久| 噼里啪啦完整版中文在线观看| 狠狠夜夜五月丁香| 九九99九九精品免费| 五月草影视| 日韩在线观看网址| 综合一本道| 激情啪啪五月| 久久久久人妻网址| 怡红院99| 999热这里只有美国精品| 色五月天成人| 色九亚洲| 五月丁香六月婷| 99久久综合精品五月天| 婷婷桃色网| 亚洲午夜一区二区| 少妇激情基地| 99精品成人无码A片观看金桔| 99视频精品全部免费观看| 极品五月天| 色女人久久| 五月丁香综合激情在线观看| 亚洲网站观看视频| 999热这里只有精品| 婷婷伊人综合中文字幕| 色婷婷电影| 激情网婷婷婷| 都市激情亚洲| 天天干,天天日| 婷婷四色成人综合色视| 综合久久首页| 久久婷婷视频| www.五月天。com| www狠狠com| 天天操人人干| 五月丁香久久久| 丁香密臀AV激情网| 色色色热| 开心婷婷五月中文字幕组| 丁香六月啪啪啪| 夜夜躁爽日日| 五月婷婷之美女图片| 中文字幕在线免费| 人妻丰满精品一区二区A片| 亚洲日日操| 婷婷天堂综合| 99在线视频网址在线观看| 天天爽天天爽| 欧美成人热| 色五月大| 97精品人人A片免费看| 五月婷婷性| 99综合| 91呦呦呦| AA久久| 天天操夜夜玩!| 日本英国美国欧美亚洲国产精亚洲日韩精品在线观看 | 婷婷五月天亚洲精品| 五月丁香六月成人| 97热91| 色婷婷九月| 久久婷婷亚洲五月天| 婷婷久久五月丁香| 婷婷五月综合丁香久久| 色婷网| 婷婷色五月天在线| 久久黄色免费视频| 丁香玖玖| 日本欧美成人片AAAA| 亚洲熟女色| 亚洲 五月 婷婷 成人| 《丁香激情综合久久伊人久久》影视在线观看 -高清预告手机免费播放 -三妹影院 | 亚洲电影在线观看| 欧洲亚洲免费视频9 | 婷婷丁香红五月91C| 大香蕉久艹| 色丁香影院| 激情四射五月天偷偷看婷婷| 天天综合网站| 伍月激情天| 99热九九在线| 夜夜嗨一区二区三区直播内容 | 丁香五月亚综合图片| 色情五月丁香婷婷网| 成人网在线视频| 免费在线观看AV网站| 97精品综合久久| 色婷婷婷婷五月天| 婷婷永久在线| 最新AV在线观看| 国产av天天插天天操天天爽| 青草五月天| 婷婷国产成人| 亚洲色综合性| 99在线观看视频蜜臀| 久9视频| 操比激情五月| 91中文狠狠综合| 欧美99热| 日韩黄黄| 无套内射极品大美女| 五月婷婷我| 久久奄也去色色网站| 天天做天天要天天爱| www.99热精品| 久久九九囯产| 婷婷六月香| 综合六月久久|