一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java Springboot集成mybatis-plus的方法是什么

java Springboot集成mybatis-plus的方法是什么

2023-05-09 01:05未知服務器之家 Java教程

今天小編給大家分享一下java Springboot集成mybatis-plus的方法是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一

今天小編給大家分享一下java Springboot集成mybatis-plus的方法是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    一、Mybatis-Plus介紹

    Mybatis-plus是Mybatis的增強工具包,其官網的介紹如下:

    • 潤物細無聲:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑。

    • 效率至上:只需簡單配置,即可快速進行單表CRUD操作,從而節省大量時間。

    • 豐富功能:代碼生成、自動分頁、邏輯刪除、自動填充等功能一應俱全。

    其優點如下:

    • 無侵入:Mybatis-Plus 在 Mybatis 的基礎上進行擴展,只做增強不做改變,引入 Mybatis-Plus 不會對您現有的 Mybatis 構架產生任何影響,而且 MP 支持所有 Mybatis 原生的特性

    • 依賴少:僅僅依賴 Mybatis 以及 Mybatis-Spring

    • 損耗小:啟動即會自動注入基本CURD,性能基本無損耗,直接面向對象操作

    • 通用CRUD操作:內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求

    • 多種主鍵策略:支持多達4種主鍵策略(內含分布式唯一ID生成器),可自由配置,完美解決主鍵問題

    • 支持ActiveRecord:支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可實現基本 CRUD 操作

    • 支持代碼生成:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用(P.S. 比 Mybatis 官方的 Generator 更加強大?。?/p>

    • 支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )

    • 內置分頁插件:基于Mybatis物理分頁,開發者無需關心具體操作,配置好插件之后,寫分頁等同于寫基本List查詢

    • 內置性能分析插件:可輸出Sql語句以及其執行時間,建議開發測試時啟用該功能,能有效解決慢查詢

    • 內置全局攔截插件:提供全表 delete 、 update 操作智能分析阻斷,預防誤操作

    二、Spring boot 整合Mybatis-plus

    2.1 pom中引入Mybatis-plus依賴

    <!--?https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter?-->
    <dependency>
    ????<groupId>com.baomidou</groupId>
    ????<artifactId>mybatis-plus-boot-starter</artifactId>
    ????<version>3.5.3.1</version>
    </dependency>

    注:如果是gradle,引入的方式如下:

    implementation group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.5.3.1'

    2.2 創建一張User表

    創建對應的數據表 Schema 的表結構和表數據:

    SET?FOREIGN_KEY_CHECKS=0;
    
    --?----------------------------
    --?Table?structure?for?`user_base_info`
    --?----------------------------
    DROP?TABLE?IF?EXISTS?`user_base_info`;
    CREATE?TABLE?`user_base_info`?(
    ??`id`?int?NOT?NULL?AUTO_INCREMENT?COMMENT?'主鍵ID',
    ??`u_id`?varchar(10)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_0900_ai_ci?NOT?NULL?COMMENT?'用戶ID',
    ??`name`?varchar(200)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_0900_ai_ci?NOT?NULL?COMMENT?'用戶名',
    ??`cn_name`?varchar(500)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_0900_ai_ci?DEFAULT?NULL?COMMENT?'中文名',
    ??`sex`?char(3)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_0900_ai_ci?NOT?NULL?COMMENT?'性別',
    ??`alias`?varchar(500)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_0900_ai_ci?DEFAULT?NULL?COMMENT?'別名',
    ??`web_chat`?varchar(200)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_0900_ai_ci?DEFAULT?NULL?COMMENT?'微信號',
    ??PRIMARY?KEY?(`id`)
    )?ENGINE=InnoDB?AUTO_INCREMENT=3?DEFAULT?CHARSET=utf8mb4?COLLATE=utf8mb4_0900_ai_ci;

    表中插入數據

    --?----------------------------
    --?Records?of?user_base_info
    --?----------------------------
    INSERT?INTO?`user_base_info`?VALUES?('1',?'001',?'holmium',?'鈥',?'1',?'虎嘯山村',?'holmium');
    INSERT?INTO?`user_base_info`?VALUES?('2',?'001',?'test',?'測試',?'0',?'美女',?'虎嘯山村');

    2.3 Mybatis-plus配置

    #mybatis-plus
    mybatis-plus:
    ??##?這個可以不用配置,因其默認就是這個路徑
    ??mapper-locations:?classpath:/mapper/*Mapper.xml
    ??#實體掃描,多個package用逗號或者分號分隔
    ??typeAliasesPackage:?com.holmium.springboot.repository.*.entity
    ??global-config:
    ????#?數據庫相關配置
    ????db-config:
    ??????#主鍵類型??AUTO:"數據庫ID自增",?INPUT:"用戶輸入ID",ID_WORKER:"全局唯一ID?(數字類型唯一ID)",?UUID:"全局唯一ID?UUID";
    ??????id-type:?AUTO
    ??????#字段策略?IGNORED:"忽略判斷",NOT_NULL:"非?NULL?判斷"),NOT_EMPTY:"非空判斷"
    ??????field-strategy:?not_empty
    ??????#駝峰下劃線轉換
    ??????column-underline:?true
    ??????#數據庫大寫下劃線轉換
    ??????#capital-mode:?true
    ??????#邏輯刪除配置
    ??????logic-delete-value:?0
    ??????logic-not-delete-value:?1
    ??????db-type:?h3
    ????#刷新mapper?調試神器
    ????refresh:?true
    ??#?原生配置
    ??configuration:
    ????map-underscore-to-camel-case:?true
    ????cache-enabled:?false

    2.4 創建一個實體

    //BasePo,后續可以繼續擴展
    @Data
    public?class?BasePo?{
    ????@TableId(value?=?"id",?type?=?IdType.AUTO)
    ????private?Integer?id;
    }
    
    package?com.holmium.springboot.infra.user.entity;
    
    import?com.baomidou.mybatisplus.annotation.TableField;
    import?com.baomidou.mybatisplus.annotation.TableName;
    import?lombok.Getter;
    import?lombok.Setter;
    
    /**
    ?*?@author?holmium
    ?*?@description:
    ?*?@date?2023年04月20日16:19
    ?*/
    @TableName(value?=?"user_base_info",?autoResultMap?=?true)
    @Getter
    @Setter
    public?class?UserPo?extends?BasePo?{
    ????/**
    ?????*?用戶ID
    ?????*/
    ????@TableField(value?=?"u_id")
    ????String?uId;
    ????/**
    ?????*?用戶名
    ?????*/
    ????@TableField(value?=?"name")
    ????String?name;
    ????/**
    ?????*?中文名稱
    ?????*/
    ????@TableField(value?=?"cn_name")
    ????String?cnName;
    ????/**
    ?????*?性別:1-男?0-女
    ?????*/
    ????@TableField(value?=?"sex")
    ????String?sex;
    ????/**
    ?????*?別名
    ?????*/
    ????@TableField(value?=?"alias")
    ????String?alias;
    ????/**
    ?????*?微信號
    ?????*/
    ????@TableField(value?=?"web_chat")
    ????String?webChat;
    }

    2.5 創建一個Mapper接口

    package?com.holmium.springboot.infra.user.mapper;
    
    import?com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import?com.holmium.springboot.infra.user.entity.UserPo;
    import?org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public?interface?UserMapper?extends?BaseMapper<UserPo>?{
    }

    2.6 修改服務接口

    //如果不理解,可以看之前的文章
    @RestController
    @RequestMapping("/user/center")
    public?class?UserApi?{
    ????@Resource
    ????UserAppImpl?userApp;
    ??
    ????@GetMapping(value?=?"/userinfo")
    ????public?UserVo?gerUserInfo(@RequestParam("id")?String?id)?throws?Exception?{
    ????????return?userApp.getUserInfoByUserId(id);
    ????}
    }

    2.7 在啟動類中添加?@MapperScan?注解,掃描 Mapper 文件夾

    @SpringBootApplication
    @MapperScan("com.holmium.springboot.infra.*.mapper")?//添加mapper掃描
    public?class?HolmiumApplication?{
    
    ????public?static?void?main(String[]?args)?{
    ????????SpringApplication.run(HolmiumApplication.class,?args);
    ????}
    
    }

    2.8 測試

    java Springboot集成mybatis-plus的方法是什么

  • 插入: 不作限制

  • 查找: 追加 where 條件過濾掉已刪除數據,且使用 wrapper.entity 生成的 where 條件會忽略該字段

  • 更新: 追加 where 條件防止更新到已刪除數據,且使用 wrapper.entity 生成的 where 條件會忽略該字段

  • 刪除: 轉變為 更新

  • @Data
    public?class?BasePo?{
    ????/**
    ?????*?主鍵
    ?????*/
    ????@TableId(value?=?"id",?type?=?IdType.AUTO)
    ????private?Integer?id;
    
    ????/**
    ?????*?是否刪除:0表示未刪除?1表示刪除.
    ?????*/
    ????@TableLogic
    ????private?Boolean?deleted;
    }

    3.3 自動填充

    實際開發中,我們會在表中記錄數據創建時間、創建人、修改時間、修改人幾個字段,但是幾個字段如果我們每次都要進行賦值,代碼比較冗余,Mybatis-plus提供的自動填充功能。

    3.3.1 增加公共屬性對象:
    @Data
    public?class?BasePo?{
    ????/**
    ?????*?主鍵
    ?????*/
    ????@TableId(value?=?"id",?type?=?IdType.AUTO)
    ????private?Integer?id;
    
    ????/**
    ?????*?創建時間
    ?????*/
    ????@TableField(fill?=?FieldFill.INSERT)
    ????@JsonFormat(pattern?=?"yyyy-MM-dd?HH:mm:ss")
    ????private?Date?createTime;
    ????/**
    ?????*?最后更新時間
    ?????*/
    ????@TableField(fill?=?FieldFill.INSERT_UPDATE)
    ????@JsonFormat(pattern?=?"yyyy-MM-dd?HH:mm:ss")
    ????private?Date?updateTime;
    ????/**
    ?????*?創建者,默認系統User?的?id?編號
    ?????*?<p>
    ?????*?使用?String?類型的原因是,未來可能會存在非數值的情況,留好拓展性。
    ?????*/
    ????@TableField(fill?=?FieldFill.INSERT,?jdbcType?=?JdbcType.VARCHAR)
    ????private?String?creator;
    ????/**
    ?????*?更新者,默認系統User?的?id?編號
    ?????*?<p>
    ?????*?使用?String?類型的原因是,未來可能會存在非數值的情況,留好拓展性。
    ?????*/
    ????@TableField(fill?=?FieldFill.INSERT_UPDATE,?jdbcType?=?JdbcType.VARCHAR)
    ????private?String?updater;
    
    ????/**
    ?????*?是否刪除
    ?????*/
    ????@TableLogic
    ????private?Boolean?deleted;
    }
    3.3.2 自定義實現類 MyMetaObjectHandler
    public?class?DefaultDbFieldHandler?implements?MetaObjectHandler?{
    
    ????@Override
    ????public?void?insertFill(MetaObject?metaObject)?{
    ????????if?(Objects.nonNull(metaObject)?&&?metaObject.getOriginalObject()?instanceof?BaseEntity)?{
    ????????????BaseEntity?baseDO?=?(BaseEntity)?metaObject.getOriginalObject();
    ????
    ????????????Date?current?=?new?Date();
    ????????????//?創建時間為空,則以當前時間為插入時間
    ????????????if?(Objects.isNull(baseDO.getCreateTime()))?{
    ????????????????baseDO.setCreateTime(current);
    ????????????}
    ????????????//?更新時間為空,則以當前時間為更新時間
    ????????????if?(Objects.isNull(baseDO.getUpdateTime()))?{
    ????????????????baseDO.setUpdateTime(current);
    ????????????}
    ????
    ????????????Long?userId?=?WebUtils.getLoginUserId();
    ????????????//?當前登錄用戶不為空,創建人為空,則當前登錄用戶為創建人
    ????????????if?(Objects.nonNull(userId)?&&?Objects.isNull(baseDO.getCreator()))?{
    ????????????????baseDO.setCreator(userId.toString());
    ????????????}
    ????????????//?當前登錄用戶不為空,更新人為空,則當前登錄用戶為更新人
    ????????????if?(Objects.nonNull(userId)?&&?Objects.isNull(baseDO.getUpdater()))?{
    ????????????????baseDO.setUpdater(userId.toString());
    ????????????}
    ????????}
    ????}
    ????
    ????@Override
    ????public?void?updateFill(MetaObject?metaObject)?{
    ????????//?更新時間為空,則以當前時間為更新時間
    ????????Object?modifyTime?=?getFieldValByName("updateTime",?metaObject);
    ????????if?(Objects.isNull(modifyTime))?{
    ????????????setFieldValByName("updateTime",?new?Date(),?metaObject);
    ????????}
    ????
    ????????//?當前登錄用戶不為空,更新人為空,則當前登錄用戶為更新人
    ????????Object?modifier?=?getFieldValByName("updater",?metaObject);
    ????????Long?userId?=?WebUtils.getLoginUserId();
    ????????if?(Objects.nonNull(userId)?&&?Objects.isNull(modifier))?{
    ????????????setFieldValByName("updater",?userId.toString(),?metaObject);
    ????????}
    ????}
    }

    3.4 條件查詢

    3.4.1 根據各種條件查詢

    Wrapper:封裝了關于查詢的各種條件方法。

    有三個子類最常用: LambdaQueryWrapper查詢條件 LambdaUpdateWrapper修改條件 LambdaQueryWrapper查詢使用lambda表達式條件

    • LambdaQueryWrapper

    selectPage(userDo,?new?LambdaQueryWrapperX<UserPo>()
    ????????????????.likeIfPresent(UserPo::getName,?userDo.getName())
    ????????????????.likeIfPresent(UserPo::getSex,?userDo.getSex())
    ????????????????.betweenIfPresent(UserPo::getCreateTime,?userDo.getCreateTime())
    ????????????????.orderByDesc(UserPo::getId))
    • LambdaUpdateWrapper

    update(update,?new?LambdaUpdateWrapper<UserPo>()
    ???????????????.eq(UserPo::getId,?id).eq(UserPo::getName,?name))
    • LambdaQueryWrapper

    new?LambdaQueryWrapper<UserDo>()
    ????????????????.eq(UserPo::getId,?id)
    ????????????????.eq(UserPo::getName,?name);

    3.5 分頁查詢

    • 添加分頁攔截器

    ???@Bean
    ???public?MybatisPlusInterceptor?mybatisPlusInterceptor()?{
    ???????MybatisPlusInterceptor?mybatisPlusInterceptor?=?new?MybatisPlusInterceptor();
    ???????//?分頁插件
    ???????mybatisPlusInterceptor.addInnerInterceptor(new?PaginationInnerInterceptor(DbType.MYSQL));
    ???????return?mybatisPlusInterceptor;
    ???}
    • 分頁查詢

    Page<UserPo>?page?=?userMapper.selectPage(page,?wrapper);//把查詢的結果自動封裝到Page對象中

    3.6 小結

    到此簡單的查詢基本已介紹完畢,可滿足他80%的日常開發需求。

    四、引入對象轉換組件mapstruct

    從上述代碼中可以看到,我們從數據庫查詢出來的結果是轉換為一個想XXXPo的對象,而接口返回的是XXXVo對象。在實際項目中,一般一個project都會分很多層,每層都會定義自己的對象,如:PO、VO、DAO、BO、DTO、POJO等等。

    • DO(Data Object):此對象與數據庫表結構一一對應,通過 DAO 層向上傳輸數據源對象。

    • DTO(Data Transfer Object):數據傳輸對象,Service 或 Manager 向外傳輸的對象。

    • BO(Business Object):業務對象,由 Service 層輸出的封裝業務邏輯的對象。

    • AO(ApplicationObject):應用對象,在Web層與Service層之間抽象的復用對象模型, 極為貼近展示層,復用度不高。

    • VO(View Object):顯示層對象,通常是 Web 向模板渲染引擎層傳輸的對象。

    • POJO是DO/DTO/BO/VO的統稱,禁止命名成xxxPOJO。

    這些對象在傳遞過程中,需要相互轉換,如果手工書寫,往往會通過getxxx,再setxxx,操作起來非常繁瑣,那有沒有一種方式比較簡單實現能?下面我們介紹一個對象轉換的組件mapstruct

    4.1 pom中引入依賴包

    <!--?https://mvnrepository.com/artifact/org.mapstruct/mapstruct?-->
    <dependency>
    ????<groupId>org.mapstruct</groupId>
    ????<artifactId>mapstruct</artifactId>
    ????<version>1.5.4.Final</version>
    </dependency>

    4.2 創建一個Convert接口

    package?com.holmium.springboot.app.user.convert;
    
    import?com.holmium.springboot.api.user.vo.UserVo;
    import?com.holmium.springboot.common.user.app.dto.UserDto;
    import?org.mapstruct.Mapper;?
    import?org.mapstruct.factory.Mappers;
    
    /**
    ?*?@author?holmium
    ?*?@date?2023年04月16日?20:24
    ?*/
    @Mapper
    public?interface?UserAppConvert?{
    ????UserAppConvert?INSTANCES?=?Mappers.getMapper(UserAppConvert.class);
    ????UserVo?voToDto(UserDto?userDto);
    }

    避坑

    這里的@Mapper注解和上述Mybatis-plus中的@Mapper注解相同,很容易引入錯誤,導致會報錯。

    這里的Mapperimport org.mapstruct.Mapper;

    mybatis-plus中的@Mapper, import org.apache.ibatis.annotations.Mapper;

    一定要注意看清楚引入的類

    4.3 在類中引用

    @Service
    public?class?UserAppImpl?implements?UserApp?{
    ????@Resource
    ????public?UserDomain?userDomain;
    ????@Override
    ????public?UserVo?getUserInfoByUserId(String?userId)?throws?Exception?{
    ????????//這樣就實現了對象轉換
    ????????return?UserAppConvert.INSTANCES.voToDto(userDomain.getUserInfoByUid(userId));
    ????}
    }

    4.4 對象屬性不同怎么轉換

    上述是兩個對象中屬性相同話,可以不用做其他任何操作,就可以事項對象互轉,但實際在開發中,兩個對象屬性不可能完全一樣。而上述操作只能將相同屬性做轉換,不同的屬性沒法互相轉換,導致對象有部分數據丟失?那怎么解決,可在轉換方法上加入@Mappings注解,如下:

    @Mapper
    public?interface?UserAppConvert?{
    
    ????UserAppConvert?INSTANCES?=?Mappers.getMapper(UserAppConvert.class);
    ????@Mappings({
    ????????????//屬性不一致轉換
    ????????????@Mapping(source?=?"name",?target?=?"userName"),
    ????????????//類型不一致轉換
    ????????????@Mapping(target?=?"createTime",?expression?=?"java(com.java.mmzsblog.util.DateTransform.strToDate(source.getCreateTime()))"),
    ????})
    ????UserVo?voToDto(UserDto?userDto);
    }

    這樣就解決了不同對象屬性和屬性類型不一致轉換問題。

    以上就是“java Springboot集成mybatis-plus的方法是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注***行業資訊頻道。

    延伸 · 閱讀

    精彩推薦
    • Java教程Java一個簡單的紅包生成算法

      Java一個簡單的紅包生成算法

      今天小編就為大家分享一篇關于Java一個簡單的紅包生成算法,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來...

      希爾伯特4392021-06-27
    • Java教程Java8 HashMap遍歷方式性能探討

      Java8 HashMap遍歷方式性能探討

      JDK8之前,可以使用keySet或者entrySet來遍歷HashMap,JDK8中引入了map.foreach來進行遍歷...

      Hosee9582022-01-07
    • Java教程JDK 7 新特性小結實例代碼解析

      JDK 7 新特性小結實例代碼解析

      這篇文章通過實例代碼給大家介紹了JDK 7 新特性小結篇,感興趣的朋友一起看看吧...

      曾夢想仗劍走天涯11712021-04-10
    • Java教程Struts2實現多文件上傳功能

      Struts2實現多文件上傳功能

      這篇文章主要為大家詳細介紹了Struts2實現多文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

      Giving_bestself2482020-12-20
    • Java教程Java SpringBoot開發小技巧詳解

      Java SpringBoot開發小技巧詳解

      這篇文章主要介紹了淺談SpringBoot項目如何讓前端開發提高效率(小技巧),主要介紹了Swagger和Nginx提高效率的方法,具有一定的參考價值,感興趣的小伙伴們...

      Keeling17208992021-12-27
    • Java教程深入理解java中的null“類型”

      深入理解java中的null“類型”

      這篇文章主要介紹了深入理解java中的null“類型”,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下...

      明明如月小角落5312021-03-29
    • Java教程java虛擬機內存溢出及泄漏實例

      java虛擬機內存溢出及泄漏實例

      本篇文章給大家分享了java虛擬機內存溢出及泄漏的實例以及相關知識點分享,有興趣的朋友參考學習下。...

      dream_sky5922021-05-10
    • Java教程mybatis多個接口參數的注解使用方式(@Param)

      mybatis多個接口參數的注解使用方式(@Param)

      這篇文章主要介紹了mybatis多個接口參數的注解使用方式(@Param),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

      阿進的寫字臺11932021-06-03
    主站蜘蛛池模板: 日本午夜色 | 91香蕉国产| 美女福利视频网站 | 日韩成人一区ftp在线播放 | 99久久国产综合精麻豆 | 4444kk在线看片 | 506rr亚洲欧美 | 91制片厂制作果冻传媒123 | 视频一区二区国产无限在线观看 | 日韩毛片免费线上观看 | 色先锋影音先锋 | 亚洲春色综合另类网蜜桃 | 国产九九在线观看播放 | 俺去俺来也在线www色官网 | 香蕉久久一区二区三区 | 亚洲 欧美 制服 校园 动漫 | 999热这里全都是精品 | 天美传媒果冻传媒星空传媒 | 无人知晓小说姜璟免费阅读 | 人人人人看人人人做人人 | 停停色| a级黄色片免费 | 日本中文字幕一区二区高清在线 | 免费看欧美一级特黄a大片一 | 国产va免费精品高清在线 | chinese老太granny| 亚洲高清网站 | 丝瓜视频看污片 | 欧美伦乱 | 免费视频片在线观看大片 | 午夜精品久久久久久久99 | 日本在线视频网 | 男人肌肌捅女人 | a级片欧美| 精品国产在天天线在线麻豆 | 闺蜜高h | darkside动漫在线观看 | 国产高清小视频 | 9久爱午夜视频 | 日本免费观看95视频网站 | 扒开老女人 |