黄a在线观看-黄a在线-黄a大片-黄色片在线看-黄色毛片免费-黄色大片网站

您的位置:首頁技術文章
文章詳情頁

Mybatis實現分表插件

瀏覽:9日期:2023-10-19 11:51:12
背景

事情是醬紫的,阿星的上級leader負責記錄信息的業務,每日預估數據量是15萬左右,所以引入sharding-jdbc做分表。

上級leader完成業務的開發后,走了一波自測,git push后,就忙其他的事情去了。

項目的框架是SpringBoot+Mybaits

出問題了

阿星負責的業務也開發完了,熟練的git pull,準備自測,單元測試run一下,上個廁所回來收工,就是這么自信。

Mybatis實現分表插件

回來后,看下控制臺,人都傻了,一片紅,內心不禁感嘆“如果這是股票基金該多好”。

出了問題就要解決,隨著排查深入,我的眉頭一皺發現事情并不簡單,怎么以前的一些代碼都報錯了?

Mybatis實現分表插件

隨著排查深入,最后跟到了Mybatis源碼,發現罪魁禍首是sharding-jdbc引起的,因為數據源是sharding-jdbc的,導致后續執行sql的是ShardingPreparedStatement。

這就意味著,sharding-jdbc影響項目的所有業務表,因為最終數據庫交互都由ShardingPreparedStatement去做了,歷史的一些sql語句因為sql函數或者其他寫法,使得ShardingPreparedStatement無法處理而出現異常。

關鍵代碼如下

Mybatis實現分表插件

發現問題后,阿星馬上就反饋給leader了。

Mybatis實現分表插件

唉,本來還想摸魚的,看來摸魚的時間是沒了,還多了一項任務。

分析

竟然交給阿星來做了,就擼起袖子開干吧,先看看分表功能的需求

支持自定義分表策略 能控制影響范圍 通用性

分表會提前建立好,所以不需要考慮表不存在的問題,核心邏輯實現,通過分表策略得到分表名,再把分表名動態替換到sql。

Mybatis實現分表插件

分表策略

為了支持分表策略,我們需要先定義分表策略抽象接口,定義如下

/** * @Author 程序猿阿星 * @Description 分表策略接口 * @Date 2021/5/9 */public interface ITableShardStrategy { /** * @author: 程序猿阿星 * @description: 生成分表名 * @param tableNamePrefix 表前綴名 * @param value 值 * @date: 2021/5/9 * @return: java.lang.String */ String generateTableName(String tableNamePrefix,Object value); /** * 驗證tableNamePrefix */ default void verificationTableNamePrefix(String tableNamePrefix){if (StrUtil.isBlank(tableNamePrefix)) { throw new RuntimeException('tableNamePrefix is null');} }}

generateTableName函數的任務就是生成分表名,入參有tableNamePrefix、value,tableNamePrefix為分表前綴,value作為生成分表名的邏輯參數。

verificationTableNamePrefix函數驗證tableNamePrefix必填,提供給實現類使用。

為了方便理解,下面是id取模策略代碼,取模兩張表

/** * @Author 程序猿阿星 * @Description 分表策略id * @Date 2021/5/9 */@Componentpublic class TableShardStrategyId implements ITableShardStrategy { @Override public String generateTableName(String tableNamePrefix, Object value) {verificationTableNamePrefix(tableNamePrefix);if (value == null || StrUtil.isBlank(value.toString())) { throw new RuntimeException('value is null');}long id = Long.parseLong(value.toString());//此處可以緩存優化return tableNamePrefix + '_' + (id % 2); }}

傳入進來的value是id值,用tableNamePrefix拼接id取模后的值,得到分表名返回。

控制影響范圍

分表策略已經抽象出來,下面要考慮控制影響范圍,我們都知道Mybatis規范中每個Mapper類對應一張業務主體表,Mapper類的函數對應業務主體表的相關sql。

阿星想著,可以給Mapper類打上注解,代表該Mpaaer類對應的業務主體表有分表需求,從規范來說Mapper類的每個函數對應的主體表都是正確的,但是有些同學可能不會按規范來寫。

假設Mpaaer類對應的是B表,Mpaaer類的某個函數寫著A表的sql,甚至是歷史遺留問題,所以注解不僅僅可以打在Mapper類上,同時還可以打在Mapper類的任意一個函數上,并且保證小粒度覆蓋粗粒度。

阿星這里自定義分表注解,代碼如下

/** * @Author 程序猿阿星 * @Description 分表注解 * @Date 2021/5/9 */@Target(value = {ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface TableShard { // 表前綴名 String tableNamePrefix(); //值 String value() default ''; //是否是字段名,如果是需要解析請求參數改字段名的值(默認否) boolean fieldFlag() default false; // 對應的分表策略類 Class<? extends ITableShardStrategy> shardStrategy();}

注解的作用范圍是類、接口、函數,運行時生效。

tableNamePrefix與shardStrategy屬性都好理解,表前綴名和分表策略,剩下的value與fieldFlag要怎么理解,分表策略分兩類,第一類依賴表中某個字段值,第二類則不依賴。

根據企業id取模,屬于第一類,此處的value設置企業id入參字段名,fieldFlag為true,意味著,會去解析獲取企業id字段名對應的值。

根據日期分表,屬于第二類,直接在分表策略實現類里面寫就行了,不依賴表字段值,value與fieldFlag無需填寫,當然你value也可以設置時間格式,具體看分表策略實現類的邏輯。

通用性

抽象分表策略與分表注解都搞定了,最后一步就是根據分表注解信息,去執行分表策略得到分表名,再把分表名動態替換到sql中,同時具有通用性。

Mybatis框架中,有攔截器機制做擴展,我們只需要攔截StatementHandler#prepare函數,即StatementHandle創建Statement之前,先把sql里面的表名動態替換成分表名。

Mybatis分表攔截器流程圖如下

Mybatis實現分表插件

Mybatis分表攔截器代碼如下,有點長哈,主流程看intercept函數就好了。

/** * @Author 程序員阿星 * @Description 分表攔截器 * @Date 2021/5/9 */@Intercepts({@Signature(type = StatementHandler.class,method = 'prepare',args = {Connection.class, Integer.class})})public class TableShardInterceptor implements Interceptor { private static final ReflectorFactory defaultReflectorFactory = new DefaultReflectorFactory(); @Override public Object intercept(Invocation invocation) throws Throwable {// MetaObject是mybatis里面提供的一個工具類,類似反射的效果MetaObject metaObject = getMetaObject(invocation);BoundSql boundSql = (BoundSql) metaObject.getValue('delegate.boundSql');MappedStatement mappedStatement = (MappedStatement)metaObject.getValue('delegate.mappedStatement');//獲取Mapper執行方法Method method = invocation.getMethod();//獲取分表注解TableShard tableShard = getTableShard(method,mappedStatement);// 如果method與class都沒有TableShard注解或執行方法不存在,執行下一個插件邏輯if (tableShard == null) { return invocation.proceed();}//獲取值String value = tableShard.value();//value是否字段名,如果是,需要解析請求參數字段名的值boolean fieldFlag = tableShard.fieldFlag();if (fieldFlag) { //獲取請求參數 Object parameterObject = boundSql.getParameterObject(); if (parameterObject instanceof MapperMethod.ParamMap) { //ParamMap類型邏輯處理MapperMethod.ParamMap parameterMap = (MapperMethod.ParamMap) parameterObject;//根據字段名獲取參數值Object valueObject = parameterMap.get(value);if (valueObject == null) { throw new RuntimeException(String.format('入參字段%s無匹配', value));}//替換sqlreplaceSql(tableShard, valueObject, metaObject, boundSql); } else { //單參數邏輯//如果是基礎類型拋出異常if (isBaseType(parameterObject)) { throw new RuntimeException('單參數非法,請使用@Param注解');}if (parameterObject instanceof Map){ Map<String,Object> parameterMap = (Map<String,Object>)parameterObject; Object valueObject = parameterMap.get(value); //替換sql replaceSql(tableShard, valueObject, metaObject, boundSql);} else { //非基礎類型對象 Class<?> parameterObjectClass = parameterObject.getClass(); Field declaredField = parameterObjectClass.getDeclaredField(value); declaredField.setAccessible(true); Object valueObject = declaredField.get(parameterObject); //替換sql replaceSql(tableShard, valueObject, metaObject, boundSql);} }} else {//無需處理parameterField //替換sql replaceSql(tableShard, value, metaObject, boundSql);}//執行下一個插件邏輯return invocation.proceed(); } @Override public Object plugin(Object target) {// 當目標類是StatementHandler類型時,才包裝目標類,否者直接返回目標本身, 減少目標被代理的次數if (target instanceof StatementHandler) { return Plugin.wrap(target, this);} else { return target;} } /** * @param object * @methodName: isBaseType * @author: 程序員阿星 * @description: 基本數據類型驗證,true是,false否 * @date: 2021/5/9 * @return: boolean */ private boolean isBaseType(Object object) {if (object.getClass().isPrimitive()|| object instanceof String|| object instanceof Integer|| object instanceof Double|| object instanceof Float|| object instanceof Long|| object instanceof Boolean|| object instanceof Byte|| object instanceof Short) { return true;} else { return false;} } /** * @param tableShard 分表注解 * @param value 值 * @param metaObject mybatis反射對象 * @param boundSql sql信息對象 * @author: 程序猿阿星 * @description: 替換sql * @date: 2021/5/9 * @return: void */ private void replaceSql(TableShard tableShard, Object value, MetaObject metaObject, BoundSql boundSql) {String tableNamePrefix = tableShard.tableNamePrefix();//獲取策略classClass<? extends ITableShardStrategy> strategyClazz = tableShard.shardStrategy();//從spring ioc容器獲取策略類ITableShardStrategy tableShardStrategy = SpringUtil.getBean(strategyClazz);//生成分表名String shardTableName = tableShardStrategy.generateTableName(tableNamePrefix, value);// 獲取sqlString sql = boundSql.getSql();// 完成表名替換metaObject.setValue('delegate.boundSql.sql', sql.replaceAll(tableNamePrefix, shardTableName)); } /** * @param invocation * @author: 程序猿阿星 * @description: 獲取MetaObject對象-mybatis里面提供的一個工具類,類似反射的效果 * @date: 2021/5/9 * @return: org.apache.ibatis.reflection.MetaObject */ private MetaObject getMetaObject(Invocation invocation) {StatementHandler statementHandler = (StatementHandler) invocation.getTarget();// MetaObject是mybatis里面提供的一個工具類,類似反射的效果MetaObject metaObject = MetaObject.forObject(statementHandler,SystemMetaObject.DEFAULT_OBJECT_FACTORY,SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,defaultReflectorFactory);return metaObject; } /** * @author: 程序猿阿星 * @description: 獲取分表注解 * @param method * @param mappedStatement * @date: 2021/5/9 * @return: com.xing.shard.interceptor.TableShard */ private TableShard getTableShard(Method method, MappedStatement mappedStatement) throws ClassNotFoundException {String id = mappedStatement.getId();//獲取Classfinal String className = id.substring(0, id.lastIndexOf('.'));//分表注解TableShard tableShard = null;//獲取Mapper執行方法的TableShard注解tableShard = method.getAnnotation(TableShard.class);//如果方法沒有設置注解,從Mapper接口上面獲取TableShard注解if (tableShard == null) { // 獲取TableShard注解 tableShard = Class.forName(className).getAnnotation(TableShard.class);}return tableShard; }}

到了這里,其實分表功能就已經完成了,我們只需要把分表策略抽象接口、分表注解、分表攔截器抽成一個通用jar包,需要使用的項目引入這個jar,然后注冊分表攔截器,自己根據業務需求實現分表策略,在給對應的Mpaaer加上分表注解就好了。

Mybatis實現分表插件

實踐跑起來

這里阿星單獨寫了一套demo,場景是有兩個分表策略,表也提前建立好了

根據id分表 tb_log_id_0 tb_log_id_1 根據日期分表 tb_log_date_202105 tb_log_date_202106

預警:后面都是代碼實操環節,請各位讀者大大耐心看完(非Java開發除外)。

TableShardStrategy定義

/** * @Author wx * @Description 分表策略日期 * @Date 2021/5/9 */@Componentpublic class TableShardStrategyDate implements ITableShardStrategy { private static final String DATE_PATTERN = 'yyyyMM'; @Override public String generateTableName(String tableNamePrefix, Object value) {verificationTableNamePrefix(tableNamePrefix);if (value == null || StrUtil.isBlank(value.toString())) { return tableNamePrefix + '_' +DateUtil.format(new Date(), DATE_PATTERN);} else { return tableNamePrefix + '_' +DateUtil.format(new Date(), value.toString());} }}** * @Author 程序猿阿星 * @Description 分表策略id * @Date 2021/5/9 */@Componentpublic class TableShardStrategyId implements ITableShardStrategy { @Override public String generateTableName(String tableNamePrefix, Object value) {verificationTableNamePrefix(tableNamePrefix);if (value == null || StrUtil.isBlank(value.toString())) { throw new RuntimeException('value is null');}long id = Long.parseLong(value.toString());//可以加入本地緩存優化return tableNamePrefix + '_' + (id % 2); }}Mapper定義

Mapper接口

/** * @Author 程序猿阿星 * @Description * @Date 2021/5/8 */@TableShard(tableNamePrefix = 'tb_log_date',shardStrategy = TableShardStrategyDate.class)public interface LogDateMapper { /** * 查詢列表-根據日期分表 */ List<LogDate> queryList(); /** * 單插入-根據日期分表 */ void save(LogDate logDate);}-------------------------------------------------------------------------------------------------/** * @Author 程序猿阿星 * @Description * @Date 2021/5/8 */@TableShard(tableNamePrefix = 'tb_log_id',value = 'id',fieldFlag = true,shardStrategy = TableShardStrategyId.class)public interface LogIdMapper { /** * 根據id查詢-根據id分片 */ LogId queryOne(@Param('id') long id); /** * 單插入-根據id分片 */ void save(LogId logId);}

Mapper.xml

<?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE mapperPUBLIC '-//mybatis.org//DTD Mapper 3.0//EN''http://mybatis.org/dtd/mybatis-3-mapper.dtd'><mapper namespace='com.xing.shard.mapper.LogDateMapper'>//對應LogDateMapper#queryList函數 <select resultType='com.xing.shard.entity.LogDate'>selectid as id,comment as comment,create_date as createDatefromtb_log_date </select>//對應LogDateMapper#save函數 <insert >insert into tb_log_date(id, comment,create_date)values (#{id}, #{comment},#{createDate}) </insert></mapper>-------------------------------------------------------------------------------------------------<?xml version='1.0' encoding='UTF-8' ?><!DOCTYPE mapperPUBLIC '-//mybatis.org//DTD Mapper 3.0//EN''http://mybatis.org/dtd/mybatis-3-mapper.dtd'><mapper namespace='com.xing.shard.mapper.LogIdMapper'>//對應LogIdMapper#queryOne函數 <select resultType='com.xing.shard.entity.LogId'>selectid as id,comment as comment,create_date as createDatefromtb_log_idwhereid = #{id} </select>//對應save函數 <insert >insert into tb_log_id(id, comment,create_date)values (#{id}, #{comment},#{createDate}) </insert></mapper>執行下單元測試

日期分表單元測試執行

@Test void test() {LogDate logDate = new LogDate();logDate.setId(snowflake.nextId());logDate.setComment('測試內容');logDate.setCreateDate(new Date());//插入logDateMapper.save(logDate);//查詢List<LogDate> logDates = logDateMapper.queryList();System.out.println(JSONUtil.toJsonPrettyStr(logDates)); }

輸出結果

Mybatis實現分表插件

id分表單元測試執行

@Test void test() {LogId logId = new LogId();long id = snowflake.nextId();logId.setId(id);logId.setComment('測試');logId.setCreateDate(new Date());//插入logIdMapper.save(logId);//查詢LogId logIdObject = logIdMapper.queryOne(id);System.out.println(JSONUtil.toJsonPrettyStr(logIdObject)); }

輸出結果

Mybatis實現分表插件

小結一下

本文可以當做對Mybatis進階的使用教程,通過Mybatis攔截器實現分表的功能,滿足基本的業務需求,雖然比較簡陋,但是Mybatis這種擴展機制與設計值得學習思考。

有興趣的讀者也可以自己寫一個,或基于阿星的做改造,畢竟是簡陋版本,還是有很多場景沒有考慮到。

另外分表的demo項目,阿星放到了Gitee,大家按需自取

Gitee地址: https://gitee.com/jxncwx/shard

項目結構:

Mybatis實現分表插件

到此這篇關于Mybatis實現分表插件的文章就介紹到這了,更多相關Mybatis 分表插件內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Mybatis 數據庫
相關文章:
主站蜘蛛池模板: 天天射天天干天天色 | 小蝌蚪av | 少妇29p| a级高清免费毛片 | 无码av波多野结衣久久 | 女人被狂c躁到高潮视频 | 中国女人一级一次看片 | 99精品久久久久久久免费看蜜月 | 午夜视频在线网站 | 天天精品免费视频 | 精品国产乱码久久久久久郑州公司 | 日韩中文字幕一区二区三区 | av淘宝国产在线观看 | 国产精品福利一区二区 | 亚洲专区路线一路线二高质量 | 日本精品一区二区三区在线观看 | 在线免费看黄色片 | 亚洲国产成人久久综合电影 | 天天操bb| 白色丝袜美女羞羞av | 夜夜爱夜夜操 | 国产又黄又爽又刺激的免费网址 | 国内精品久久久久久久影视蜜臀 | 伊人久久一区二区三区 | 免费观看添你到高潮视频 | 黑人粗硬进入过程视频 | 成人精品视频在线看 | 亚洲精品国偷拍自产在线观看蜜桃 | 一区二区午夜 | 久草综合网 | 国产精品一区二区在线观看网站 | 极品尤物一区二区三区 | 国产精品短视频 | 色www亚洲国产阿娇yao | 少妇大叫好爽受不了午夜视频 | 91嫩草香蕉| 欧美高清性xxxxhd | 曰批全过程免费视频在线观看无码 | 日韩精品人妻系列无码专区 | 欧美黑人性暴力猛交喷水 | 在线成人免费观看www | 国产影视一区二区 | 久久九精品 | 我要色综合天天 | 国产97色在线 | 欧美一区二区三区成人精品 | www.91在线视频| 汤唯的三级av在线播放 | 痴汉电车在线播放 | 伊人色综合久久天天五月婷 | 国产二区精品 | 国产极品美女高潮无套在线观看 | 久久天天躁夜夜躁狠狠躁2022 | 理论片午午伦夜理片久久 | 日韩av片无码一区二区不卡电影 | 日产精品入口 | 同性情a三级a三级a三级 | 99re在线视频精品 | 久久精品一日日躁夜夜躁 | 久久精品亚洲国产奇米99 | 免费看av毛片 | 亚洲色图图片 | 日日夜夜爱爱 | 夜夜躁日日躁狠狠久久av | 97爱爱视频 | 国产麻豆一区二区三区在线观看 | aaa日本高清在线播放免费观看 | 国产精品乱码久久久久 | 六月婷婷色 | 欧美一级欧美三级在线观看 | 日本不卡网 | 主播av在线 | 男女下面一进一出无遮挡 | 日日噜噜噜噜人人爽日本精品 | 国产69精品麻豆 | 97视频在线看 | 高hhhhh| 日本老妇做爰xxx视频 | 久久久sm调教网站 | 俄罗斯少妇性高清ⅹxx | 国产精品av在线免费观看 | 日本不卡一区二区三区 | a级在线播放| 亚洲成a人蜜臀av在线播放 | 全国男人天堂网 | 国产白丝jk捆绑束缚调教视频 | 欧美日韩免费一区 | 日韩久久久久久 | 国产欧美久久久久 | 成人在线视频免费看 | 精品免费视频一区二区 | 日本一区二区免费看 | 欧美高清二区 | 懂色av噜噜一区二区三区av88 | 日韩女同疯狂作爱系列5 | 亚洲人av在线| 国产特级毛片潘金莲 | 91精品在线播放 | 精品国产一区二区三区久久 | 在线精品无码字幕无码av | 69xav| 福利一区二区在线 | 国产中文字幕一区二区三区 | 日韩一区二区三区精品视频 | wwwyoujizzcom中国版| 欧美精品二区三区 | 夜夜偷天天爽夜夜爱 | 精品久久www| 久久久久久久国产精品毛片 | 性一交一乱一乱一视频 | 婷婷五月综合色中文字幕 | 国产黄频 | 国产日韩一级片 | 成年人香蕉视频 | 久久综合噜噜激激的五月天 | 国产精品久久久久9999小说 | 日韩伊人久久 | 老色鬼在线精品视频 | 色与欲影视天天看综合网 | 久久免费视频观看 | 少妇特黄a一区二区三区 | 另类欧美日韩 | 中文字幕日韩人妻不卡一区 | 国产欧美一区二区三区四区 | 天天躁久久躁日日躁 | 色婷婷久| 正在播放重口老熟女露脸 | 捆绑裸体绳奴bdsm亚洲 | www亚洲精品少妇裸乳一区二区 | 性猛交xxxxx按摩中国 | 亚洲在av人极品无码网站 | 伊人www22综合色 | 欧美视频日韩 | 看全色黄大色黄大片 视频 欧美深度肠交惨叫 | 亚州视频在线 | 比色毛片 | 日本道精品一区二区三区 | 悠悠色在线| 久久嫩草精品久久久精品才艺表演 | 成人免费看www网址入口 | 日韩天天干 | 国产亚洲精品久久yy50 | 男女插插视频 | 亚洲另类伦春色综合小说 | aa免费视频 | 66m66成人摸人视频 | 国产做爰全免费的视频软件 | 成年人视频网 | 看曰本女人大战黑人视频 | 精精国产xxxx视频在线 | 亚洲日韩av无码一区二区三区人 | 一本色道久久加勒比精品 | 国产伦精品一区二区三区免.费 | 日躁夜躁狠狠躁2020 | 国产老妇av | av成人免费在线观看 | 丰满爆乳无码一区二区三区 | 妺妺窝人体色www在线下载 | 国产乱对白精彩 | 欧美成人吸奶水做爰 | 新疆少妇xxxx做受 | 中文字幕av观看 | 一本色道久久亚洲精品加勒比 | 亚洲国产日韩欧美在线观看 | 亚洲码国产精品高潮在线 | 国产成人av免费观看 | 三级三级久久三级久久18 | 欧美另类一区二区 | 日本三级日本三级韩国三级视 | 丰满少妇一级片 | 欧美xxxx做受欧美 | 亚洲一区二区三区四 | www中文字幕综合码 ww成人 | 少妇无码太爽了在线播放 | 国产精品污www一区二区三区 | 国产成人精选视频在线观看 | 日韩av成人在线 | 污污网站在线免费观看 | 欧美图片一区二区 | 瑟瑟网站在线观看 | 亚洲精品国产a | 精品国产乱码久久久久久移动网络 | 好吊色欧美一区二区三区视频 | 国产成人精品亚洲男人的天堂 | 一级片在线放映 | 日产精品久久久久久久蜜臀 | 久热精品在线观看视频 | 亚洲视频导航 | 亚洲一区中文字幕永久在线 | 精品国产18久久久久久二百 | 国产精品免费福利 | 午夜精品三级久久久有码 | 国产偷国产偷av亚洲清高 | 国产女人18毛片 | 国产99久久久国产精品下药 | 明星换脸av一区二区三区网站 | 米奇av| 亚洲欧美乱综合图片区小说区 | 啦啦啦www播放日本观看 | 一级做受大片免费视频 | 日产精品久久久一区二区福利 | 日本中文字幕在线视频 | 一边摸一边添高潮av | 天天插天天爽 | 欧美做爰一区二区三区 | 亚洲日韩男人网在线 | 开元在线观看视频国语 | 久久盗摄| yy1111111少妇影院乱码 | 久久免费一区 | 欧美国产日韩久久mv | 国产特黄特色大片免费视频 | 亚洲人成在线影院 | 亚洲香蕉久久 | 欧美牲交a欧美牲交aⅴ免费下载 | 黄色一级免费网站 | 国产精品成人品 | 一本大道一区二区 | 手机av免费在线 | 国模私拍av| 天堂在线中文 | 国产免费视频在线 | 精品中文字幕一区 | 欧美日韩一区二区区别是什么 | 国产乱码一区二区三区 | 黄色网址你懂得 | 欧美日韩中文 | 婷婷四房综合激情五月 | 黑人大长吊大战中国人妻 | 精品xxx| 尤物视频网站在线观看 | 91精品国产色综合久久不卡98口 | av一区二区免费 | 国产中文字幕在线观看 | 日韩欧美在线视频免费观看 | 久久久久99精品久久久久 | 亚洲欧美综合精品另类天天更新 | 麻豆性视频 | 国产高清无套内谢 | 欧美亚洲日本一区 | 日产精品久久久久久久 | 在线观看毛片视频 | 中文字幕一区二区三三 | 免费久草视频 | 国产精品美女久久久久 | 潘金莲三级野外 | 永久在线视频 | 国产激情精品视频 | 老汉色老汉首页a亚洲 | 激情五月中文字幕 | a√视频在线观看 | 一区二区视频网 | 四虎影视在线影院在线观看免费视频 | 日本公妇乱淫免费视频一区三区 | 亚洲一区网站 | 鸭子tv国产在线永久播放 | 欧美少妇xxxxx | 国内精品久久久久久久97牛牛 | 天天插夜夜爽 | 久久99精品久久久久久久清纯 | 国产高清视频在线免费观看 | 免费在线一区二区 | 91精选视频| 亚洲xxxx视频 | 国产91精品一区二区三区四区 | 国产精品久久久久高潮 | av成人在线看 | 色爱综合网 | 日韩xxxx视频 | 久久精品成人一区二区三区蜜臀 | 毛片网站免费 | 99国产精品一区二区 | 中出一区 | 日本在线看片免费人成视频1000 | 日日摸夜夜添夜夜添一区二区 | 大尺度做爰啪啪床戏 | 久久亚洲经典 | 久久美女性网 | 日本一卡2卡三卡4卡免费网站 | 亚洲人妖女同在线播放 | 亚洲视频一区二区在线观看 | 狠狠色婷婷久久综合频道日韩 | 日韩av手机在线观看 | 欧美成人精品一区二区三区在线观看 | 国产精品久久久久久久久久大牛 | 日本一区二区三区日本免费 | 中文字幕38页 | 精品国产一区二区三区四区阿崩 | 久草网视频 | 亚洲精品一区二区三 | 美女销魂一区二区 | 成年人网站在线免费观看 | 欧美福利在线观看 | 亚洲日本va中文字幕 | 国产精品久久久久久久久妇女 | 高潮添下面视频免费看 | 国产亚洲欧美一区 | 麻豆三级| 91亚洲精品久久久中文字幕 | 亚洲国产成人a精品不卡在线 | 亚洲视频免费在线 | 亚洲小说春色综合另类 | 久久99婷婷国产精品免费 | 欧美日韩在线播放视频 | 97国精产品无人区一码二码 | 色综合天天 | 美女午夜激情 | 女同久久另类99精品蜜臀 | 亚洲一区二区三区无码久久 | 亚洲日韩乱码中文字幕 | 在线播放免费人成毛片乱码 | 国产精品久久久久久av免费看 | 久久99精品久久久久久噜噜 | 极品少妇网站 | 熟妇人妻系列aⅴ无码专区友真希 | 精品久久久久久久中文字幕 | 在线观看中文字幕码 | 亚洲女同女同女同女同女同69 | 91最新地址永久入口 | 国产精品自在在线午夜出白浆 | 成人手机视频在线观看 | 国产极品美女高潮无套久久久 | 午夜性 | 黄片毛片在线观看 | 亚洲综合无码精品一区二区三区 | 久久精品国产99久久久 | 亚洲欧美日韩中文字幕一区二区三区 | 偷窥四川少妇野外啪啪 | 2020毛片 | 女人高潮被爽到呻吟在线观看 | 精品人伦一区二区色婷婷 | 国产国产精品人在线观看 | 国产成人久久久 | 精品国产一区二区三区久久 | 天天爱天天插 | 肥臀熟女一区二区三区 | 欧美va亚洲va在线观看 | 老司机午夜剧场 | sese久久| 7777少妇色视频免费播放 | 在线视频日韩 | 欧美色综合天天久久综合精品 | 在线国产二区 | 色哟哟一区二区三区 | 国产无遮挡又黄又爽免费网站 | 成人av福利| 欧美影院adc| www.亚洲色图 | 四虎色播 | av手机在线看片 | 国产剧情自拍 | 亚洲 欧美 日韩 在线 | 精品一区二区在线视频 | 一本久道久久综合婷婷五月 | 女女百合高h喷汁呻吟视频 女女百合国产免费网站 | 国产区图片区小说区亚洲区 | 狠狠人妻久久久久久综合蜜桃 | 亚洲国产精品成人无久久精品 | 中国美女一级黄色片 | 日本特黄特色大片免费视频老年人 | 狠狠操中文字幕 | 手机看片久久 | 欧美日韩一级在线观看 | 日本道之久久综合久久爱 | 日韩精品一卡2卡3卡4卡乱码的功能 | 波多野结衣一区二区三区高清 | 无码人妻av一二区二区三区 | 欧美激情视频一区 | 蜜臀久久99静品久久久久久 | 国产成人久久777777 | 久久久精品麻豆 | 国产美女免费看 | 国偷自产av一区二区三区小尤奈 | 国产精品久久久久影院嫩草 | 欧美白嫩少妇xxxxx性 | 韩国成人在线 | 牛牛影视一区二区 | 5999在线视频免费观看 | 97精品视频在线播放 | 久久网站免费看 | 与子敌伦刺激对白播放的优点 | 日产国产精品亚洲系列 | 亚洲精品久久久久avwww潮水 | 强壮公侵犯使我夜夜高潮 | 国产乱了真实在线观看 | 久久久久久免费观看 | 91理论片午午伦夜理片久久 | 久久国产午夜精品理论片推荐 | 午夜性视频 | 97视频在线免费 | 激情伊人 | 国产丰满麻豆videossex | 99re6在线视频精品免费 | 国产精品乱码一区二区三区视频 | 欧美亚洲综合视频 | 成人午夜精品无码区久久 | 亚洲成人网在线播放 | 波多野结衣精品一区二区三区 | 成人在线综合 | 风流还珠之乱淫h文 | 亚洲色图偷| 亚洲乱码日产精品bd在线看 | 粉嫩av一区二区三区免费看 | 国产av毛片| 天天综合天天添夜夜添狠狠添 | 亚洲人女屁股眼交3之懂色 亚洲人屁股眼子交1 | 五月综合激情婷婷六月色窝 | 国产无遮挡又黄又爽免费网站 | 欧美三级不卡 | 日日躁夜夜摸月月添添添的视频 | 国产艳妇av在线观看果冻传媒 | 国产多p混交群体交乱 | 亚洲中文字幕久久无码精品 | 丁香啪啪综合成人亚洲 | 污网站在线观看免费 | 日本a级在线 | 免费观看性生交大片3 | 日韩人妻无码免费视频一区二区三区 | 天天操操操 | 无码人妻一区二区三区在线视频 | 色综合天天综合网国产成人网 | 22222se男人的天堂 | 国产粗话肉麻对白 | 欧美一区1区三区3区公司 | 精品人妻少妇一区二区三区在线 | 久久福利网站 | 国产91精品看黄网站在线观看动漫 | 尹人综合| 麻豆成人久久精品二区三区免费 | 动漫美女靠逼 | 日韩精品无码一本二本三本色 | 日韩高清片 | 农村人伦偷精品视频a人人澡 | 久久久久噜噜噜亚洲熟女综合 | 精东av在线 | 精品无人国产偷自产在线 | 美女视频黄a视频全免费 | 亚洲看片lutube在线观看 | 国产欧美日韩中文字幕 | 懂色a v| 久久人人爽人人人人爽av | 欧美成人综合色 | av观看免费 | 河北彩花中文字幕 | 成人调教视频 | 少妇高潮喷水惨叫久久久久电影 | 久久久www成人免费精品 | 国产手机在线视频 | 黄色激情视频网站 | 国产免费av片在线观看 | 免费国产黄网站在线观看可以下载 | 天天操天天操天天射 | 999精欧美一区二区三区黑人 | 无套内谢孕妇毛片免费看看 | 人妻人人做人做人人爱 | 高清国产午夜精品久久久久久 | 三级a三级三级三级a十八发禁止 | 国产在线麻豆精品观看 | 熟妇人妻无码xxx视频 | 久久久久久久久久久久久久久 | 亚洲国产又黄又爽女人高潮的 | 91狠狠狠狠狠狠狠狠 | 人人爽人人爽人人片av亚洲 | 成人无码精品一区二区三区 | 欧美精品在线免费观看 | 法国人性生活xxxx | 中文在线一区二区三区 | 久久精品中文闷骚内射 | 日韩av无码中文无码不卡电影 | 久久先锋男人av资源网站 | 无码成人1000部免费视频 | 男人天堂99 | 免费一区 | 日韩精品成人免费观看视频 | 日本大香伊一区二区三区 | jzzjzz日本丰满成熟少妇 | 黄在线免费观看 | 欧美绿帽合集xxxxx | 四虎影院色 | 三级av在线免费观看 | 激情五月在线 | 亚洲精品视频免费看 | 亚洲一区精品二人人爽久久 | 女人裸体性做爰视频 | 少妇又紧又大又色又爽视频 | 一区二区国产精品精华液 | 草色网| 日韩美女av在线 | 欧美日韩国产在线观看 | 国内黄色网址 | 蜜桃网站入口在线进入 | 日日干天天 | 波多野结衣丝袜 | 日韩中文字幕区一区有砖一区 | 日本大尺度吃奶呻吟视频 | 午夜在线不卡 | 亚洲偷自拍另类图片二区 | 亚洲精品国产精品乱码视色 | 九色蜜桃臀丨porny丨自拍 | 日皮毛片 | 99久久婷婷国产综合精品草原 | 2019日韩中文字幕mv | 免费观看a级毛片在线播放 免费观看a级片 | 久久一区二区三区四区 | 欧美11p| 久久久久久美女 | 久久久久久福利 | 无码国模国产在线观看 | 宅男噜噜噜66网站在线观看 | 少妇视频一区 | 亚洲精品国产一区二区在线观看 | 小早川怜子xxxxaⅴ在线 | 91精品无人区麻豆乱码1区2区介绍 | 97在线免费视频 | 久久福利在线 | 午夜尤物丰满大乳美女 | 国内精品视频一区 | 国产情侣激情自拍 | 日韩精品第二页 | 亚洲第9页| 99国产精品永久免费视频 | 亚洲va欧美va人人爽 | 免费观看全黄做爰大片国产 | 性生交大片免费看狂欲 | 国产乱子伦视频一区二区三区 | 国产精品自拍在线 | 天天久| 精品国产麻豆免费人成网站 | 午夜精品久久久久久久爽 | 国产成人亚洲综合无码精品 | 一级色网站 | 久久女 | 国产偷人妻精品一区 | 久久国产精品99久久久久久丝袜 | 色狠狠久久av大岛优香 | 精品看片 | 曰本无码人妻丰满熟妇啪啪 | 在线观看av网站 | 国内精品国产成人国产三级 | 激情文学欧美 | 极品尤物一区二区三区 | 天堂网2021天堂手机版 | 国产美女黄色片 | 欧美a级理论片 | 日本aⅴ免费视频一区二区三区 | 日本精品三级 | 日韩中文字幕在线观看 | 少妇久久人人爽人人爽人人片欧美 | 老熟女高潮喷水了 | 亚洲一区精品二人人爽久久 | 亚洲欧美一区二区三区国产精品 | 欧洲av片 | 丰满的少妇xxxxx人伦理 | 91福利在线观看 | 男人边做边吃奶头视频 | 一级少妇片 | 手机在线看片日韩 | 精品国产乱码久久久久久竹菊影视 | 夜夜高潮夜夜爽国产伦精品 | 东北妇女精品bbwbbw | 一区二区午夜 | 在线免费你懂的 | 国模妙妙超大尺度啪啪人体 | 欧美日韩精品久久久免费观看 | 尤物视频一区 | 国产99久久久国产精品成人免费 | 国产精品激情av久久久青桔 | 国产图片区| 日本视频高清一区二区三区 | 91夫妻视频| 无遮挡很爽很污很黄的网站 | 精品免费在线视频 | 九九九九九精品 | 亚洲第十页 | 国精产品一区一区三区视频 | 久久人人爽人人爽人人片av东京热 | 免费无码肉片在线观看 | 美女黄色毛片视频 | 亚洲国产成人精品女人 | 欧美另类专区 | 国产口爆吞精在线视频 | 国产精品区免费视频 | 日本老熟妇毛茸茸 | 狠狠操夜夜 | 日本一级大片 | 国产清纯白嫩初高中在线观看性色 | 国产suv精品一区88l | 国产对白受不了了中文对白 | 在线尤物 | eeuss鲁片一区二区三区69 | 午夜影院在线 | 亚洲乱强伦 | 日韩欧美在线免费 | 亚洲精品乱码久久久久久蜜桃 | 中文字幕第一页av | 国内精品久久久久精免费 | 377p粉嫩日本欧洲色噜噜 | 久热一区 | 强伦人妻一区二区三区视频18 | 国产一级片视频 | 中文乱码字慕人妻熟女人妻 | 国产无遮挡又黄又爽免费网站 | 国产人妖视频 | 国产经典三级 | 夜夜夜高潮夜夜爽夜夜爰爰 | 无码人妻精品一区二区蜜桃色欲 | 丰满放荡岳乱妇91ww | 美女av一区二区 | 日日爽天天 | 免费看无码毛视频成片 | 久久久精品小视频 | 国产黄色片在线免费观看 | 亚洲成人精品一区 | 国产精品毛片久久久久久久 | 日韩人妻不卡一区二区三区 |