精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一種避免寫大量CRUD方法的新思路

開發(fā) 架構(gòu)
今天,我繼續(xù)給大家?guī)硪粋€超級無敵霹靂的編碼新招式,來自我最近的親身實(shí)踐,我把公司的PHP工程(兩個端,幾百個接口)重構(gòu)到Java工程上來,僅僅用了兩天!

哈嘍,各位代碼戰(zhàn)士們,我是Jensen,一個夢想著和大家一起在代碼的海洋里遨游,順便撿起那些散落的知識點(diǎn)的程序員小伙伴。

今天,我繼續(xù)給大家?guī)硪粋€超級無敵霹靂的編碼新招式,來自我最近的親身實(shí)踐,我把公司的PHP工程(兩個端,幾百個接口)重構(gòu)到Java工程上來,僅僅用了兩天!

先看看業(yè)務(wù)——租賃平臺領(lǐng)域圖:

乍一看這張領(lǐng)域圖就不簡單(表梳理、核心業(yè)務(wù)梳理、建模等花了我兩天),順便用腳趾頭數(shù)了一下,總共是36張表,只談常規(guī)CRUD方法的話,要寫36*4=144個API接口,這里還涉及客戶端和管理端API的隔離,那翻個倍就是288個API接口了唄。

CrudBoy是不可能的,這輩子都不可能的。

你信不信,我只寫兩個Controller,就能把兩個端的CRUD全部搞定!

本文涉及技術(shù)點(diǎn):SpringMVC、MybatisPlus。

一、思路分析

問題來了,一個Controller怎么做到多張表的CRUD(增刪查改)呢?

要做到所有表共用一個Controller,就需要復(fù)用公共的CRUD方法。我們需要滿足以下5個條件:

  • 不同的表需要通過模型名稱進(jìn)行隔離
  • 通過模型名稱能找到對應(yīng)的模型類
  • 通過模型類能找到對應(yīng)的倉庫,從而操作數(shù)據(jù)庫
  • 對于查詢方法,請求參數(shù)能轉(zhuǎn)化為查詢條件,模型作為查詢返回類
  • 對于操作方法,請求參數(shù)能轉(zhuǎn)化為模型

只需要解決上述問題,一個Controller即可解決所有表的CRUD需求。

老規(guī)矩——設(shè)計(jì)先行:

好吧,我承認(rèn)這張圖是剛臨時畫的,代碼早就已經(jīng)實(shí)現(xiàn)了,正如你的產(chǎn)品經(jīng)理告訴你:

開發(fā)小哥哥,客戶說后天要上線這個新功能,能不能拜托你今天把這個小需求開發(fā)完,晚上測試完就能發(fā)布上線了唄。

你不得不用腦子先畫個藍(lán)圖,邊寫代碼邊小步迭代,做完后再補(bǔ)設(shè)計(jì)。

二、先造輪子

首先來個聚合控制器接口AggregateController:

/**
 * 聚合控制器,實(shí)現(xiàn)該控制器的Controller,自帶CRUD方法
 *
 * @author Jensen
 * @公眾號 架構(gòu)師修行錄
 */
public interface AggregateController {
    // 公共POST分頁
    @PostMapping("/{modelName}/page")
    default Page<Model> postPage(@PathVariable("modelName") String modelName, @RequestBody Map<String, Object> query) {
        return convertQuery(getModelClass(modelName), query).page();
    }
    // 公共GET分頁
    @GetMapping("/{modelName}/page")
    default Page<Model> getPage(@PathVariable("modelName") String modelName, Map<String, Object> query) {
        return convertQuery(getModelClass(modelName), query).page();
    }
    // 公共POST列表
    @PostMapping("/{modelName}/list")
    default List<Model> postList(@PathVariable("modelName") String modelName, @RequestBody Map<String, Object> query) {
        return convertQuery(getModelClass(modelName), query).list();
    }
    // 公共GET列表
    @GetMapping("/{modelName}/list")
    default List<Model> getList(@PathVariable("modelName") String modelName, Map<String, Object> query) {
        return convertQuery(getModelClass(modelName), query).list();
    }
    // 公共詳情,通過其他條件查第一條
    @GetMapping("/{modelName}/detail")
    default Model detail(@PathVariable("modelName") String modelName, Map<String, Object> query) {
        return convertQuery(getModelClass(modelName), query).first();
    }
    // 公共詳情,通過ID查
    @GetMapping("/{modelName}/detail/{id}")
    default Model detail(@PathVariable("modelName") String modelName, @PathVariable("id") String id) {
        return BaseRepository.of(getModelClass(modelName)).get(id);
    }
    // 公共創(chuàng)建
    @PostMapping({"/{modelName}/save", "/{modelName}/create"})
    default Model save(@PathVariable("modelName") String modelName, @RequestBody Map<String, Object> query) {
        Model model = convertModel(getModelClass(modelName), query);
        model.save();
        return model;
    }
    // 公共批量創(chuàng)建
    @PostMapping("/{modelName}/saveBatch")
    default void saveBatch(@PathVariable("modelName") String modelName, @RequestBody List<Map<String, Object>> params) {
        Class<Model> modelClass = getModelClass(modelName);
        BaseRepository.of(modelClass).save(convertModels(modelClass, params));
    }
    // 公共修改
    @PostMapping({"/{modelName}/update", "/{modelName}/modify"})
    default void update(@PathVariable("modelName") String modelName, @RequestBody Map<String, Object> query) {
        convertModel(getModelClass(modelName), query).update();
    }
    // 公共刪除
    @PostMapping({"/{modelName}/delete/{id}", "/{modelName}/remove/{id}"})
    default void delete(@PathVariable("modelName") String modelName, @PathVariable("id") String id) {
        BaseRepository.of(getModelClass(modelName)).delete(id);
    }
    // 通過模型名找到模型類
    static Class<Model> getModelClass(String modelName) {
        Class<Model> modelClass = MappingKit.get("MODEL_NAME", modelName);
        BizAssert.notNull(modelClass, "Model: {} not found", modelName);
        return modelClass;
    }
    // 通過模型類找到查詢類,并把Map參數(shù)轉(zhuǎn)換為查詢參數(shù)
    static Query convertQuery(Class<Model> modelClass, Map<String, Object> queryMap) {
        Class<Query> queryClass = MappingKit.get("MODEL_QUERY", modelClass);
        BizAssert.notNull(queryClass, "Query not found");
        return BeanKit.ofMap(queryMap, queryClass);
    }
    // 通過Map參數(shù)轉(zhuǎn)換為模型
    static Model convertModel(Class<Model> modelClass, Map<String, Object> modelMap) {
        return BeanKit.ofMap(modelMap, modelClass);
    }
}

路徑參數(shù){modelName}就是模型名,比如建了個表user_info,對應(yīng)的模型是UserInfo,對應(yīng)的模型名叫userInfo。

下一步,我們需要通過這個動態(tài)的模型名路由到對應(yīng)的模型上,怎么做呢?

這時候,我們需要在應(yīng)用啟動時,在初始化倉庫實(shí)現(xiàn)類中獲取到模型后,注入到一個容器。

這里我們先定義一個基礎(chǔ)倉庫接口:

/**
 * 基礎(chǔ)倉庫接口
 * 針對CRUD進(jìn)行封裝,業(yè)務(wù)倉庫需要實(shí)現(xiàn)當(dāng)前接口
 *
 * @author Jensen
 * @公眾號 架構(gòu)師修行錄
 */
public interface BaseRepository<M extends Model, Q extends Query> {
    // 定義一個存放模型類/查詢類-倉庫實(shí)現(xiàn)類映射的容器
    Map<Class<?>, Class<?>> REPOSITORY_MAPPINGS = new ConcurrentHashMap<>();
    /**
     * 注入倉庫類
     *
     * @param mappingClass    Model類/Query類
     * @param repositoryClass 倉庫類
     */
    static <R extends BaseRepository> void inject(Class<?> mappingClass, Class<R> repositoryClass) {
        REPOSITORY_MAPPINGS.put(mappingClass, repositoryClass);
    }
    // TODO 封裝的CRUD方法暫且略過
}

上面這種使用ConcurrentHashMap作為容器的技術(shù),在各個框架里隨處可見,還是挺實(shí)用的,大家可以學(xué)一學(xué)。

接下來,我們再對MybatisPlus的BaseMapper類進(jìn)行淺封裝,作為基礎(chǔ)倉庫實(shí)現(xiàn)類,針對CRUD進(jìn)行二次封裝:

/**
 * 基礎(chǔ)倉庫實(shí)現(xiàn)類
 * 針對CRUD進(jìn)行封裝,業(yè)務(wù)倉庫實(shí)現(xiàn)需要繼承當(dāng)前類
 *
 * @author Jensen
 * @公眾號 架構(gòu)師修行錄
 */
public abstract class BaseRepositoryImpl<MP extends BaseMapper<P>, M extends Model, P, Q extends Query> implements BaseRepository<M, Q>, Serializable {


    // 在倉庫實(shí)現(xiàn)類構(gòu)造器中初始化各種映射信息
    public BaseRepositoryImpl() {
        // 通過反射工具,拿到具體的模型類
        final Class<M> modelClass = (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), 1);
        // 通過反射工具,拿到具體的持久化實(shí)體類
        final Class<P> poClass = (Class<P>) ReflectionKit.getSuperClassGenericType(this.getClass(), 2);
        // 通過反射工具,拿到具體的查詢類
        final Class<Q> queryClass = (Class<Q>) ReflectionKit.getSuperClassGenericType(this.getClass(), 3);
        // 注入模型類-倉庫實(shí)現(xiàn)類
        BaseRepository.inject(modelClass, this.getClass());
        // 注入查詢類-倉庫實(shí)現(xiàn)類
        BaseRepository.inject(queryClass, this.getClass());
        // 映射模型類-實(shí)體類
        MappingKit.map("MODEL_PO", modelClass, poClass);
        MappingKit.map("MODEL_PO", poClass, modelClass);
       // 映射模型類-查詢類
        MappingKit.map("MODEL_QUERY", modelClass, queryClass);
        MappingKit.map("MODEL_QUERY", queryClass, modelClass);
        // 映射模型名-模型類,模型名首字母設(shè)為小寫(駝峰式命名)
        String modelClassName = modelClass.getSimpleName().toLowerCase().substring(0, 1) + modelClass.getSimpleName().substring(1);
        MappingKit.map("MODEL_NAME", modelClassName, modelClass);
    }
    
    // TODO 封裝的CRUD方法暫且略過
}

上面的MappingKit是封裝好的用于Bean映射的容器工具類:

/**
 * 用于任意對象映射,按biz隔離(為了復(fù)用)
 */
@UtilityClass
public final class MappingKit {
    // Bean容器
    private final Map<String, Map<Object, Object>> BEAN_MAPPINGS = new ConcurrentHashMap<>();


    public <K, V> void map(String biz, K key, V value) {
        Map<Object, Object> mappings = BEAN_MAPPINGS.get(biz);
        if (mappings == null) {
            mappings = new ConcurrentHashMap<>();
            BEAN_MAPPINGS.put(biz, mappings);
        }
        mappings.put(key, value);
    }


    public <K, V> V get(String field, K source) {
        Map<Object, Object> mappings = BEAN_MAPPINGS.get(field);
        if (mappings == null) return null;
        return (V) mappings.get(source);
    }
}

注入的邏輯比較簡單,就是建一個Map<String, Class>,key放模型名,Class放Model類,這樣就可以通過模型名找到對應(yīng)的Model類了。

在倉庫實(shí)現(xiàn)類初始化時,我們把其他必要信息先進(jìn)行映射,如通過Model類找RepositoryImpl倉庫實(shí)現(xiàn)、通過Model類找Query類等等。

至此,我們把映射的工作完成了,大家可以回過頭看看AggregateController,就是實(shí)際通過模型名modelName從容器中取出模型類、模型類取出倉庫的過程了。

還看不懂沒關(guān)系,結(jié)合上面的AC架構(gòu)圖,重新理解幾遍~

三、造完輪子,開車!

打開方式很簡單,比如我按端隔離定義了下面兩個控制器,僅僅用幾行代碼就代替了288個API接口的編寫:

/**
 * 客戶端控制器
 */
@RestController
@RequestMapping("/client")
public class ClientController implements AggregateController {

}
/**
 * 管理端控制器
 */
@RestController
@RequestMapping("/admin")
public class AdminController implements AggregateController {


}

四、寫在最后

希望今天分享的AC架構(gòu)能提高大家CRUD的效率,也讓系統(tǒng)重構(gòu)不再可怕。

對了,我把它的完整版集成到了我的D3Boot(DDD快速啟動)開源基礎(chǔ)框架內(nèi),也有適用于部分場景使用的CRUDController,大家需要的話可以移步Gitee抄作業(yè)。

責(zé)任編輯:姜華 來源: 架構(gòu)師修行錄
相關(guān)推薦

2024-04-26 08:58:54

if-else代碼JavaSpring

2024-05-09 08:20:29

AC架構(gòu)數(shù)據(jù)庫冗余存儲

2022-06-23 07:05:46

跳板機(jī)服務(wù)器PAM

2023-09-17 23:16:46

緩存數(shù)據(jù)庫

2016-10-26 09:12:58

2018-04-18 07:34:58

2025-01-27 13:00:00

2020-11-27 14:45:57

開發(fā)服務(wù)器代碼

2019-11-22 09:21:17

技術(shù)研發(fā)數(shù)據(jù)

2016-10-13 10:57:55

phptcp專欄

2017-08-24 15:02:01

前端增量式更新

2021-05-18 06:22:39

CSS 制作波浪技巧

2017-01-23 11:18:16

戴爾

2009-12-03 10:32:21

2018-12-14 14:30:12

安全檢測布式系測試

2011-07-04 17:53:48

快速測試

2021-06-11 00:11:23

GPS數(shù)據(jù)協(xié)議

2010-03-26 13:34:47

CentOS安裝

2015-05-07 14:24:36

everRun

2018-02-08 08:11:41

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

国产成人a亚洲精品| 欧美性感一类影片在线播放| 97国产超碰| 黄色一级免费视频| 大型av综合网站| 精品高清美女精品国产区| 精品国产综合久久| 波多野结衣一二区| 99久久精品网| 欧美成人免费网站| 亚洲乱码中文字幕久久孕妇黑人| 国产香蕉在线| 久久99精品久久久| 亚洲欧美日韩网| 五月天av在线播放| 免费大片在线观看www| 久久电影国产免费久久电影 | 一区二区三区精品99久久| 亚洲无吗一区二区三区| 污污在线观看| 久久麻豆一区二区| 成人免费福利视频| 亚洲天堂日韩av| 欧美a级片视频| 亚洲国产精品热久久| 中文字幕国产传媒| av免费不卡| 国产精品网站在线观看| 国产精品久久精品国产| 天天爱天天做天天爽| 欧美成人嫩草网站| 亚洲天堂第一页| 少妇欧美激情一区二区三区| 欧美性猛交xxx高清大费中文| 最新成人av在线| 免费毛片一区二区三区久久久| 伊人亚洲综合网| 亚洲美女啪啪| 久久国产精品偷| 亚洲第一成人网站| 无人区乱码一区二区三区| 色乱码一区二区三区88 | 欧美国产激情| 亚洲护士老师的毛茸茸最新章节 | 秋霞网一区二区三区| 北条麻妃一区二区三区在线观看| 欧美在线视频日韩| 精品这里只有精品| 七七久久电影网| 国产女同性恋一区二区| 精品综合在线| 亚洲欧美另类视频| 日本欧美大码aⅴ在线播放| 国内偷自视频区视频综合| 四虎地址8848| 精品一区二区三区在线| 精品无人区乱码1区2区3区在线| 搡的我好爽在线观看免费视频| 忘忧草在线www成人影院| 精品久久久久久久久久久久久久 | 亚洲视频国产| 在线不卡的av| 午夜免费精品视频| 欧美大片免费| 狠狠色狠狠色综合日日五| 国产91沈先生在线播放| 黄色网页在线看| 国产精品私房写真福利视频| 日本电影一区二区三区| 国产又爽又黄网站亚洲视频123| 国产69精品一区二区亚洲孕妇| 成人网页在线免费观看| 中文字幕视频一区二区| 蜜臀av国产精品久久久久| 国产精品igao视频| 国产又粗又猛又黄视频| 日韩制服丝袜av| 日本乱人伦a精品| 亚洲 欧美 日韩 在线| 久久久久久一区二区| 日av在线播放中文不卡| 日韩精品在线一区二区三区| 三级一区在线视频先锋| 国产mv久久久| 一级片一区二区三区| 国产精品一区二区免费不卡 | 伊人伊人伊人久久| 调教驯服丰满美艳麻麻在线视频| 成人激情开心网| 日韩一区二区欧美| 全网免费在线播放视频入口| 欧美电影一区| 欧美成人精品一区二区三区| 午夜剧场免费在线观看| 国产精品av久久久久久麻豆网| 欧美国产日韩一区二区| 日韩 国产 欧美| 激情综合色丁香一区二区| 99久久综合狠狠综合久久止| 五月天丁香视频| 日本一区二区综合亚洲| 中文字幕欧美日韩一区二区| 怡红院红怡院欧美aⅴ怡春院| 亚洲国产精品天堂| 国产精品动漫网站| 日韩精品三级| 亚洲美女性视频| 免费91在线观看| 91久久在线| 国产精品主播视频| 成人午夜免费在线观看| 久久嫩草精品久久久精品| 亚洲精品在线免费| 国内在线视频| 91久久香蕉国产日韩欧美9色| 手机在线观看日韩av| 亚洲精品白浆高清| 久久深夜福利免费观看| 日韩黄色一级大片| 视频在线观看国产精品| 亚洲精品女av网站| 欧洲天堂在线观看| 亚洲视频狠狠干| 熟女性饥渴一区二区三区| 9999精品视频| 亚洲精品天天看| 日本精品人妻无码77777| 免费一级欧美片在线播放| 国产精品免费视频久久久| 国产精品无码天天爽视频| 91日韩在线专区| 中文字幕一区二区中文字幕| 亚洲日本天堂| 欧美变态tickle挠乳网站| 国精产品一区一区二区三区mba| 丝袜脚交一区二区| 女同一区二区| 绿色成人影院| 日韩av在线资源| 久久9999久久免费精品国产| 国产福利电影一区二区三区| 中文字幕av久久| 亚洲老司机网| 日韩在线观看免费全| 一二三区中文字幕| 亚洲国产精品99久久久久久久久| 日本三区在线观看| 教室别恋欧美无删减版| 日韩免费视频在线观看| 可以直接在线观看的av| 一本色道久久综合亚洲91| 最新中文字幕视频| 久久国产99| 农村寡妇一区二区三区| 四虎4545www精品视频| 国产亚洲欧洲在线| 亚洲网站在线免费观看| 最新欧美精品一区二区三区| 午夜免费福利网站| 亚洲网色网站| 国产伦精品一区二区三区| 1区2区在线| 亚洲美女在线视频| 波多野结衣一二区| 亚洲视频在线观看一区| 久久久九九九热| 亚洲乱码久久| 欧美精品免费观看二区| 成人涩涩视频| 久久精品色欧美aⅴ一区二区| 国产三级午夜理伦三级| 中文字幕综合网| 国产无套精品一区二区三区| 日韩视频二区| 日韩资源av在线| **国产精品| 久久久久久综合网天天| 青青草超碰在线| 欧美另类变人与禽xxxxx| 久久久久久久久久久久久女过产乱| 国产精品99久久久久久久女警| 菠萝蜜视频在线观看入口| 欧美xxxx在线| 91精品久久久久久久久久久| 欧美性video| 亚洲人成电影网站| 国产色视频在线| 精品久久久久久中文字幕大豆网| 青娱乐国产视频| 国产成人啪免费观看软件| 日韩精品视频一区二区在线观看| 成人黄色av| 黑人另类av| 在线高清欧美| 18性欧美xxxⅹ性满足| 在线观看美女网站大全免费| 日韩精品一区二区三区中文精品| 天堂在线免费观看视频| 亚洲欧美日韩人成在线播放| 变态另类丨国产精品| 久久国产麻豆精品| 成人免费观看cn| 日本久久一二三四| 国产精品一级久久久| 99久久er| 欧美一级片一区| 1区2区3区在线视频| 国产亚洲精品久久久优势| 国产高清免费观看| 欧美性受xxxx| 国产精品男女视频| 亚洲午夜精品久久久久久久久| 性欧美一区二区| 97久久精品人人做人人爽| 污污的视频免费观看| 亚洲综合二区| 国产精品久久久久久久乖乖| 欧美电影一二区| 日本视频一区二区在线观看| 成功精品影院| 96国产粉嫩美女| 成人四虎影院| 国产成人一区三区| 亚洲天堂av在线| 国内精品国产三级国产在线专| 日本韩国在线视频爽| 亚洲日韩欧美视频一区| 免费看黄色一级视频| 欧美一区二区三区免费| 中文字幕免费观看视频| 色88888久久久久久影院野外| 日韩av一二三区| 亚洲永久精品国产| 91视频青青草| 中文字幕一区日韩精品欧美| 精品熟妇无码av免费久久| 国产欧美精品区一区二区三区| 午夜理伦三级做爰电影| 久久婷婷久久一区二区三区| 精品国产人妻一区二区三区| 成人久久视频在线观看| 又黄又色的网站| 高清视频一区二区| 催眠调教后宫乱淫校园| 成人精品高清在线| 国产污在线观看| 北条麻妃一区二区三区| 黄色av电影网站| 成人av资源站| 毛茸茸free性熟hd| 91在线观看污| 97伦伦午夜电影理伦片| 久久久www成人免费毛片麻豆| 青青草视频播放| 91丨九色丨国产丨porny| 色天使在线视频| 国产亚洲欧美在线| 色屁屁草草影院ccyy.com| 中文字幕中文字幕一区二区| 久久国产波多野结衣| 亚洲精品视频一区| 日韩手机在线观看| 欧美色欧美亚洲高清在线视频| 最近免费中文字幕大全免费版视频| 在线看日本不卡| 国产精品久久久久久久久久久久久久久久久久 | 最新欧美日韩亚洲| 午夜激情一区| 亚洲人成无码网站久久99热国产| 国产精品夜夜夜| 天堂中文视频在线| 韩日欧美一区二区三区| 日本美女视频网站| 久久久久久久电影| 99久久久无码国产精品不卡| 亚洲精品中文在线观看| 久草国产精品视频| 欧美性猛片aaaaaaa做受| 国产xxxx孕妇| 国产婷婷成人久久av免费高清| 日韩a在线观看| 中文字幕欧美视频在线| 亚洲91av| 日本高清不卡的在线| 亚洲日日夜夜| 久久riav二区三区| 色爱综合网欧美| 欧美一级免费播放| 美女视频黄久久| 香港三级日本三级| 国产精品色婷婷| 亚洲精品午夜久久久久久久| 日本久久电影网| 亚洲av无码国产精品永久一区| 日韩精品视频免费专区在线播放| 香蕉视频在线播放| 992tv在线成人免费观看| 亚洲欧美专区| 六十路精品视频| 欧美有码视频| 欧美性猛交久久久乱大交小说| 国产成人自拍在线| 天堂资源在线视频| 精品久久久久久久久久| 97caocao| 亚洲欧美另类国产| 免费av不卡在线观看| 国产精品视频永久免费播放| 国产精品对白久久久久粗| 亚洲一区二区三区精品在线观看| 亚洲黄色av| 国产欧美精品一二三| 久久久精品人体av艺术| 国产亚洲精品码| 欧美日韩国产综合一区二区三区| 天堂а√在线8种子蜜桃视频 | 日韩福利在线视频| 亚洲成人www| 国产毛片毛片毛片毛片毛片| 亚洲欧美日韩精品久久亚洲区 | 日本不卡免费高清视频| 在线观看视频一区二区三区| 四虎一区二区| 久久一二三四| 日本护士做爰视频| 亚洲综合网站在线观看| 99久久久国产精品无码免费| 在线观看亚洲区| 欧洲精品一区二区三区| 欧美xxxx黑人又粗又长精品| 亚洲激情av| 亚洲av成人精品一区二区三区| 亚洲欧美另类在线| 亚洲一卡二卡在线| 国产亚洲成av人片在线观看桃| 女厕盗摄一区二区三区| 99精彩视频| 欧美精品啪啪| 欧美色图校园春色| 亚洲色图一区二区| 国产剧情精品在线| 久久久国产精品免费| 亚洲热av色在线播放| 一区二区成人国产精品 | 无人码人妻一区二区三区免费| 国产精品人人做人人爽人人添| 瑟瑟视频在线免费观看| 亚洲天堂av高清| 超碰这里只有精品| 午夜欧美性电影| 欧美a级理论片| 欧美日韩国产黄色| 欧美高清www午色夜在线视频| 伊人免费在线| 91丝袜美腿美女视频网站| 天天做天天爱天天综合网2021| 日韩精品aaa| 亚洲综合在线第一页| 亚洲精品久久久蜜桃动漫| 97视频免费在线看| 日韩深夜影院| 欧美日韩第二页| 欧美国产精品中文字幕| 在线免费观看一级片| 久久香蕉频线观| 久久97久久97精品免视看秋霞| 人妻熟女一二三区夜夜爱| 国产日本欧洲亚洲| 国产一区二区在线不卡| 欧美精品性视频| 美女午夜精品| 污污视频网站免费观看| 中文字幕亚洲在| 成 人片 黄 色 大 片| 午夜精品理论片| 国产影视一区| 91丝袜超薄交口足| 亚洲国产一区视频| 国产高清av在线| 亚洲一区二区在线播放| 亚洲福利免费| 国产精成人品免费观看| 91麻豆精品国产91久久久资源速度| 手机av在线播放| 欧美日韩精品久久久免费观看| 蜜臀精品久久久久久蜜臀| 欧美高清视频一区二区三区| 日韩av中文字幕在线播放| 久久91视频| 国产美女主播在线| 国产女主播视频一区二区| 午夜精品久久久久久久99| 日本精品视频在线| 亚洲影视一区二区三区| xxxx黄色片| 欧美精品tushy高清| 国产伦理精品| a级黄色片网站| 久久综合狠狠综合久久综合88| 国产精品久久久久久久久久久久久久久久 |