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

我們一起聊聊枚舉規(guī)范化

開發(fā) 前端
使用 CommonEnum 最大的好處便是可以進行統(tǒng)一管理,對于統(tǒng)一管理,第一件事便是找到并注冊所有的 CommonEnum 實現(xiàn)。

1. 規(guī)范&封裝

凡是只給規(guī)范,不給封裝和工具的都是耍流氓。

規(guī)范是靠不住的,如果想保障落地質(zhì)量必須對最佳實踐進行封裝!

  1. 規(guī)范靠人來執(zhí)行,但人是最靠不住的!
  2. 封裝復用才是王道,才是保障落地質(zhì)量的重要手段。

1.1. 規(guī)范化枚舉

枚舉僅提供了 name 和 ordrial 兩個特性,而這兩個特性在重構(gòu)時都會發(fā)生變化,為了更好的解決枚舉的副作用,我們通過接口為其添加了新能力:

  1. 添加 code 用作枚舉的唯一標識
  2. 添加 description 用于統(tǒng)一枚舉的展示

圖片圖片

image

為此,還定義了兩個接口

  1. CodeBasedEnum 提供 getCode 方法,增加唯一標識
  2. SelfDescribedEnum 提供 getDescription 方法,增加枚舉的描述信息

在這兩個接口基礎之上,可以構(gòu)建出通用枚舉 CommonEnum,定義如下:

// 定義統(tǒng)一的枚舉接口
public interface CommonEnum extends CodeBasedEnum, SelfDescribedEnum{

}

整體結(jié)構(gòu)如下:

圖片圖片

在定義枚舉時便可以直接實現(xiàn) CommonEnum 這個接口。示例代碼如下:

public enum CommonOrderStatus implements CommonEnum {
    CREATED(1, "待支付"),
    TIMEOUT_CANCELLED(2, "超時取消"),
    MANUAL_CANCELLED(5, "手工取消"),
    PAID(3, "支付成功"),
    FINISHED(4, "已完成");
    private final int code;
    private final String description;

    CommonOrderStatus(int code, String description) {
        this.code = code;
        this.description = description;
    }

    @Override
    public String getDescription() {
        return description;
    }

    @Override
    public int getCode() {
        return this.code;
    }
}

1.2. 統(tǒng)一管理 CommonEnum

使用 CommonEnum 最大的好處便是可以進行統(tǒng)一管理,對于統(tǒng)一管理,第一件事便是找到并注冊所有的 CommonEnum 實現(xiàn)。整體架構(gòu)如下:

圖片圖片

核心處理流程如下:

  1. 首先通過 Spring 的 ResourcePatternResolver 根據(jù)配置的 basePackage 對 classpath 進行掃描
  2. 掃描結(jié)果以 Resource 來表示,通過 MetadataReader 讀取 Resource 信息,并將其解析為 ClassMetadata
  3. 獲得 ClassMetadata 之后,找出實現(xiàn) CommonEnum 的類
  4. 將 CommonEnum 實現(xiàn)類注冊到兩個 Map 中進行緩存

備注:此處萬萬不可直接使用反射技術(shù),反射會觸發(fā)類的自動加載,將對眾多不需要的類進行加載,從而增加 metaspace 的壓力。

在需要 CommonEnum 時,只需注入 CommonEnumRegistry Bean 便可以方便的獲得 CommonEnum 的全部實現(xiàn)。

1.3. Spring MVC 集成

有了統(tǒng)一的 CommonEnum,便可以對枚舉進行統(tǒng)一管理,由框架自動完成與 Spring MVC 的集成。集成內(nèi)容包括:

  1. 使用 code 作為輸入?yún)?shù)的唯一標識,避免 name、ordrial 變化導致業(yè)務異常
  2. 對返回值展示信息包括枚舉的 code、name、description 等信息
  3. 基于 CommonEnumRegistry 提供通用的枚舉字典

整體架構(gòu)如下:

圖片圖片

1.3.1. 入?yún)⒓?/h4>

核心就是以 code 作為枚舉的唯一標識,自動完成 code 到枚舉的轉(zhuǎn)化。

Spring MVC 存在兩種參數(shù)轉(zhuǎn)化擴展:

  1. 對于普通參數(shù),比如 RequestParam 或 PathVariable 直接從 ConditionalGenericConverter 進行擴展

基于 CommonEnumRegistry 提供的 CommonEnum 信息,對 matches 和 getConvertibleTypes方法進行重寫

根據(jù)目標類型獲取所有的 枚舉值,并根據(jù) code 和 name 進行轉(zhuǎn)化

  1. 對于 Json 參數(shù),需要對 Json 框架進行擴展(以 Jackson 為例)
  2. 遍歷 CommonEnumRegistry 提供的所有 CommonEnum,依次進行注冊

  3. 從 Json 中讀取信息,根據(jù) code 和 name 轉(zhuǎn)化為確定的枚舉值

兩種擴展核心實現(xiàn)見:

@Order(1)
@Component
public class CommonEnumConverter implements ConditionalGenericConverter {
    @Autowired
    private CommonEnumRegistry enumRegistry;

    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
        Class<?> type = targetType.getType();
        return enumRegistry.getClassDict().containsKey(type);
    }

    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return enumRegistry.getClassDict().keySet().stream()
                .map(cls -> new ConvertiblePair(String.class, cls))
                .collect(Collectors.toSet());
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        String value = (String) source;
        List<CommonEnum> commonEnums = this.enumRegistry.getClassDict().get(targetType.getType());
        return commonEnums.stream()
                .filter(commonEnum -> commonEnum.match(value))
                .findFirst()
                .orElse(null);
    }
}

static class CommonEnumJsonDeserializer extends JsonDeserializer{
        private final List<CommonEnum> commonEnums;

        CommonEnumJsonDeserializer(List<CommonEnum> commonEnums) {
            this.commonEnums = commonEnums;
        }

        @Override
        public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
            String value = jsonParser.readValueAs(String.class);
            return commonEnums.stream()
                    .filter(commonEnum -> commonEnum.match(value))
                    .findFirst()
                    .orElse(null);
        }
    }

1.3.2. 返回集成

默認情況下,對于枚舉類型在轉(zhuǎn)換為 Json 時,只會輸出 name,其他信息會出現(xiàn)丟失,對于展示非常不友好,對此,需要對 Json 序列化進行能力增強。

首先,需要定義 CommonEnum 對應的返回對象,具體如下:

@Value
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@ApiModel(description = "通用枚舉")
public class CommonEnumVO {
    @ApiModelProperty(notes = "Code")
    private final int code;

    @ApiModelProperty(notes = "Name")
    private final String name;

    @ApiModelProperty(notes = "描述")
    private final String desc;

    public static CommonEnumVO from(CommonEnum commonEnum){
        if (commonEnum == null){
            return null;
        }
        return new CommonEnumVO(commonEnum.getCode(), commonEnum.getName(), commonEnum.getDescription());
    }

    public static List<CommonEnumVO> from(List<CommonEnum> commonEnums){
        if (CollectionUtils.isEmpty(commonEnums)){
            return Collections.emptyList();
        }
        return commonEnums.stream()
                .filter(Objects::nonNull)
                .map(CommonEnumVO::from)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
}

CommonEnumVO 是一個標準的 POJO,只是增加了 Swagger 相關(guān)注解。

CommonEnumJsonSerializer 是自定義序列化的核心,會將 CommonEnum 封裝為 CommonEnumVO 并進行寫回,具體如下:

static class CommonEnumJsonSerializer extends JsonSerializer{

        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            CommonEnum commonEnum = (CommonEnum) o;
            CommonEnumVO commonEnumVO = CommonEnumVO.from(commonEnum);
            jsonGenerator.writeObject(commonEnumVO);
        }
    }

1.3.3. 通用枚舉字典

有了 CommonEnum 之后,可以提供統(tǒng)一的枚舉字典接口,避免重復開發(fā),同時在新增枚舉時也無需編碼,系統(tǒng)自動識別并添加到字典中。

在 CommonEnumRegistry 基礎之上實現(xiàn)通用字典接口非常簡單,只需按規(guī)范構(gòu)建 Controller 即可,具體如下:

@Api(tags = "通用字典接口")
@RestController
@RequestMapping("/enumDict")
@Slf4j
public class EnumDictController {
    @Autowired
    private CommonEnumRegistry commonEnumRegistry;

    @GetMapping("all")
    public RestResult<Map<String, List<CommonEnumVO>>> allEnums(){
        Map<String, List<CommonEnum>> dict = this.commonEnumRegistry.getNameDict();
        Map<String, List<CommonEnumVO>> dictVo = Maps.newHashMapWithExpectedSize(dict.size());
        for (Map.Entry<String, List<CommonEnum>> entry : dict.entrySet()){
            dictVo.put(entry.getKey(), CommonEnumVO.from(entry.getValue()));
        }
        return RestResult.success(dictVo);
    }

    @GetMapping("types")
    public RestResult<List<String>> enumTypes(){
        Map<String, List<CommonEnum>> dict = this.commonEnumRegistry.getNameDict();
        return RestResult.success(Lists.newArrayList(dict.keySet()));
    }

    @GetMapping("/{type}")
    public RestResult<List<CommonEnumVO>> dictByType(@PathVariable("type") String type){
        Map<String, List<CommonEnum>> dict = this.commonEnumRegistry.getNameDict();
        List<CommonEnum> commonEnums = dict.get(type);

        return RestResult.success(CommonEnumVO.from(commonEnums));
    }
}

該 Controller 提供如下能力:

  1. 獲取全部字典,一次性獲取系統(tǒng)中所有的 CommonEnum
  2. 獲取所有字典類型,僅獲取字典類型,通常用于測試
  3. 獲取指定字典類型的全部信息,比如上述所說的填充下拉框

1.4. 存儲層集成

存儲層并沒有提供足夠的擴展能力,并不能自動向框架注冊類型轉(zhuǎn)換器。但,由于邏輯都是想通的,框架提供了公共父類來實現(xiàn)復用。

1.4.1. MyBatis 集成

CommonEnumTypeHandler 實現(xiàn) MyBatis 的 BaseTypeHandler接口,為 CommonEnum 提供的通用轉(zhuǎn)化能力,具體如下:

public abstract  class CommonEnumTypeHandler<T extends Enum<T> & CommonEnum>
        extends BaseTypeHandler<T> {
    private final List<T> commonEnums;

    protected CommonEnumTypeHandler(T[] commonEnums){
        this(Arrays.asList(commonEnums));
    }

    protected CommonEnumTypeHandler(List<T> commonEnums) {
        this.commonEnums = commonEnums;
    }

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, T t, JdbcType jdbcType) throws SQLException {
        preparedStatement.setInt(i, t.getCode());
    }

    @Override
    public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException {

        int code = resultSet.getInt(columnName);
        return commonEnums.stream()
                .filter(commonEnum -> commonEnum.match(String.valueOf(code)))
                .findFirst()
                .orElse(null);
    }

    @Override
    public T getNullableResult(ResultSet resultSet, int i) throws SQLException {
        int code = resultSet.getInt(i);
        return commonEnums.stream()
                .filter(commonEnum -> commonEnum.match(String.valueOf(code)))
                .findFirst()
                .orElse(null);
    }

    @Override
    public T getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        int code = callableStatement.getInt(i);
        return commonEnums.stream()
                .filter(commonEnum -> commonEnum.match(String.valueOf(code)))
                .findFirst()
                .orElse(null);
    }
}

由于邏輯比較簡單,在此不做過多解釋。

1.4.2. JPA 集成

CommonEnumAttributeConverter 實現(xiàn) JPA 的 AttributeConverter 接口,為 CommonEnum 提供的通用轉(zhuǎn)化能力,具體如下:

public abstract class CommonEnumAttributeConverter<E extends Enum<E> & CommonEnum>
        implements AttributeConverter<E, Integer> {
    private final List<E> commonEnums;

    public CommonEnumAttributeConverter(E[] commonEnums){
        this(Arrays.asList(commonEnums));
    }

    public CommonEnumAttributeConverter(List<E> commonEnums) {
        this.commonEnums = commonEnums;
    }

    @Override
    public Integer convertToDatabaseColumn(E e) {
        return e.getCode();
    }

    @Override
    public E convertToEntityAttribute(Integer code) {
        return (E) commonEnums.stream()
                .filter(commonEnum -> commonEnum.match(String.valueOf(code)))
                .findFirst()
                .orElse(null);
    }
}

2. 應用示例

在有封裝后,業(yè)務代碼將變的非常簡單。

2.1. 項目配置

由于是在 lego 項目中進行的封裝,第一步便是引入lego依賴,具體如下:

<dependency>
    <groupId>com.geekhalo.lego</groupId>
    <artifactId>lego-starter</artifactId>
    <version>0.1.23</version>
</dependency>

為了能自動識別 CommonEnum 的實現(xiàn),需要指定掃描包,具體如下:

baseEnum:
  basePackage: com.geekhalo.demo

項目啟動時,CommonEnumRegistry 會自動掃描包下的 CommonEnum 實現(xiàn),并完成注冊。

最后,需要在啟動類上增加如下配置:

@ComponentScan(value = "com.geekhalo.lego.core.enums")

從而,讓 Spring完成核心組件的加載。

2.2. Spring MVC 示例

完成以上配置后,Spring MVC 就已經(jīng)完成集成。新建一個 OrderStatus 枚舉,具體如下:

public enum CommonOrderStatus implements CommonEnum {
    CREATED(1, "待支付"),
    TIMEOUT_CANCELLED(2, "超時取消"),
    MANUAL_CANCELLED(5, "手工取消"),
    PAID(3, "支付成功"),
    FINISHED(4, "已完成");
    private final int code;
    private final String description;

    CommonOrderStatus(int code, String description) {
        this.code = code;
        this.description = description;
    }

    @Override
    public String getDescription() {
        return description;
    }

    @Override
    public int getCode() {
        return this.code;
    }
}

2.2.1. 入?yún)⑹纠?/h4>

如下圖所示:

圖片圖片

可見,status:3 系統(tǒng)自動轉(zhuǎn)換為 PAID,成功完成了 code 到 CommonOrderStatus 的轉(zhuǎn)換。

2.2.2. 返回結(jié)果示例

圖片圖片

返回結(jié)果也不再是簡單的name,而是一個對象,返回字段包括:code、name、desc 等。

2.2.3. 通用字典示例

通過 swagger 可以看到增加一個字典Controller 如下:

圖片圖片

/enumDict/types 返回已加載的所有字段類型,如下所示:

圖片圖片


系統(tǒng)中只有一個實現(xiàn)類 CommonOrderStatus,新增實現(xiàn)類會自動出現(xiàn)在這里。

/enumDict/all 返回所有字典信息,如下所示:

圖片圖片

一次性返回全部字典信息。

/enumDict/{type} 返回指定字典信息,如下所示:

圖片圖片

指定返回 CommonOrderStatus 字典。

2.3. 存儲層示例

有了可復用的公共父類后,類型轉(zhuǎn)換器變的非常簡單。

2.3.1. MyBatis 類型轉(zhuǎn)化器

MyBatis 類型轉(zhuǎn)換器只需繼承自 CommonEnumTypeHandler 即可,具體代碼如下:

@MappedTypes(CommonOrderStatus.class)
public class CommonOrderStatusTypeHandler extends CommonEnumTypeHandler<CommonOrderStatus> {
    public CommonOrderStatusTypeHandler() {
        super(CommonOrderStatus.values());
    }
}

當然,別忘了添加 MyBatis 配置:

mybatis:
  type-handlers-package: com.geekhalo.demo.enums.code.fix

2.3.2. JPA 類型轉(zhuǎn)化器

JPA 類型轉(zhuǎn)化器只需繼承自 CommonEnumAttributeConverter 即可,具體代碼如下:

@Converter(autoApply = true)
public class CommonOrderStatusAttributeConverter extends CommonEnumAttributeConverter<CommonOrderStatus> {
    public CommonOrderStatusAttributeConverter() {
        super(CommonOrderStatus.values());
    }
}

如有必要,可以在實體類的屬性上增加 注解,具體如下:

/**
 * 指定枚舉的轉(zhuǎn)換器
 */
@Convert(converter = CommonOrderStatusAttributeConverter.class)
private CommonOrderStatus status;

3. 示例&源碼

代碼倉庫:https://gitee.com/litao851025/learnFromBug

代碼地址:https://gitee.com/litao851025/learnFromBug/tree/master/src/main/java/com/geekhalo/demo/enums/support

責任編輯:武曉燕 來源: geekhalo
相關(guān)推薦

2023-06-09 07:48:20

數(shù)字化轉(zhuǎn)型工具

2023-01-04 18:10:26

服務模塊化jre

2023-06-30 08:18:51

敏捷開發(fā)模式

2023-08-10 08:28:46

網(wǎng)絡編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-09-10 21:42:31

2024-02-20 21:34:16

循環(huán)GolangGo

2021-08-27 07:06:10

IOJava抽象

2024-07-26 09:47:28

2022-10-08 00:00:05

SQL機制結(jié)構(gòu)

2022-02-23 08:41:58

NATIPv4IPv6

2022-09-22 08:06:29

計算機平板微信

2024-11-28 09:57:50

C#事件發(fā)布器

2021-08-12 07:49:24

mysql

2023-07-24 09:41:08

自動駕駛技術(shù)交通

2023-03-26 23:47:32

Go內(nèi)存模型

2023-07-27 07:46:51

SAFe團隊測試

2023-12-28 09:55:08

隊列數(shù)據(jù)結(jié)構(gòu)存儲

2022-10-28 07:27:17

Netty異步Future
點贊
收藏

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

日韩天堂在线| 三级视频在线看| 精品视频久久| 4438x亚洲最大成人网| 红桃一区二区三区| 日韩福利一区二区| 久久精品国产精品亚洲综合| 欧美高清视频在线观看| 91精品国产自产| 狠狠久久伊人中文字幕| 亚洲一区av在线| 秋霞久久久久久一区二区| 国产一区二区三区四区视频 | 免费成人av在线播放| 久久天天躁狠狠躁夜夜av| 中文字幕天堂av| 欧美大陆国产| 日韩欧美极品在线观看| 欧美一级中文字幕| 成人av一区| av在线一区二区| 91久久嫩草影院一区二区| 美日韩一二三区| 欧美亚洲不卡| 日韩少妇与小伙激情| 中文人妻一区二区三区| 深夜激情久久| 欧美日韩不卡在线| 国产xxxxx在线观看| 在线观看三级视频| 中文字幕中文字幕在线一区 | 欧美亚洲精品在线观看| 久久精品99久久久| 国产精品久久色| 国产一级在线免费观看| 五月综合激情| 在线亚洲午夜片av大片| 久久精品国产亚洲AV熟女| 国产精品115| 欧美一区二区三区小说| 天天爽人人爽夜夜爽| 英国三级经典在线观看| 午夜激情久久久| 日韩一级性生活片| 国内在线免费视频| 亚洲午夜日本在线观看| 亚洲色婷婷久久精品av蜜桃| 国产区在线看| 亚洲日本乱码在线观看| 亚洲一区二区免费视频软件合集 | 欧美激情免费视频| 91嫩草|国产丨精品入口| 99热国内精品永久免费观看| 日韩天堂在线视频| 激情高潮到大叫狂喷水| 日韩欧美精品一区| 日韩午夜在线视频| 国产免费美女视频| 亚洲a在线视频| 久久视频在线观看免费| 自拍偷拍第9页| 天天做天天爱天天综合网| 精品久久久91| 欧美丰满熟妇bbbbbb| 午夜日韩激情| 久久久久久中文| www.国产高清| 蜜桃视频一区| 国产美女精彩久久| 国产女人高潮毛片| 懂色av一区二区三区蜜臀| 国产精品久久久对白| 天天操天天操天天| 久久久天堂av| 在线观看国产一区| 日本性爱视频在线观看| 午夜国产精品影院在线观看| 韩国日本在线视频| 91av一区| 日韩欧美国产综合| 亚洲国产欧美视频| 成人在线一区| 欧美国产日韩一区二区在线观看 | 成人情视频高清免费观看电影| 亚洲欧美另类视频| 久久亚洲二区三区| 老司机av福利| 日本在线播放一二三区| 欧美三级一区二区| www.四虎在线| 国产99亚洲| 久久亚洲影音av资源网| 欧美日韩精品区| 久久国产精品区| 国产伦精品一区二区三毛| 加勒比一区二区三区在线| 亚洲日本欧美天堂| 国产综合免费视频| 国产精品美女久久久久人| 日韩av最新在线| 在线观看天堂av| 亚洲视频大全| 91在线视频免费| 美州a亚洲一视本频v色道| 中文字幕日韩av资源站| 欧美日韩精品在线一区二区 | 欧美撒尿777hd撒尿| av不卡中文字幕| 清纯唯美综合亚洲| 97在线视频免费| 国产精品无码免费播放| 久久嫩草精品久久久精品| 欧美 亚洲 视频| 黄色成人在线观看网站| 亚洲激情在线视频| 91九色丨porny丨极品女神| 麻豆91精品| 国产精品一 二 三| 国产精品刘玥久久一区| 一本色道亚洲精品aⅴ| 亚洲少妇一区二区三区| 婷婷综合伊人| 国产美女精品视频免费观看| 日本大片在线观看| 亚洲电影一级黄| 18深夜在线观看免费视频| 日本道不卡免费一区| 欧美又大又粗又长| 免费观看黄一级视频| 亚洲男女毛片无遮挡| 亚洲国产日韩欧美在线观看| 亚洲精华一区二区三区| 隔壁老王国产在线精品| 国产黄色一区二区| 亚洲人xxxx| 欧美一级视频在线| 人人狠狠综合久久亚洲婷| 日韩免费观看av| 欧美在线一卡| 岛国精品视频在线播放| 人妻 丝袜美腿 中文字幕| 一精品久久久| 亚洲qvod图片区电影| 一区二区高清不卡| 欧美午夜一区二区| 国产91丝袜美女在线播放| 噜噜噜躁狠狠躁狠狠精品视频 | 国产精品69av| 韩日视频在线| 在线视频国内一区二区| 蜜桃av乱码一区二区三区| 蜜桃伊人久久| 日韩一本精品| 男人亚洲天堂| 久久av.com| www.我爱av| 亚洲一二三区在线观看| 亚洲自拍偷拍精品| 国产日韩1区| 欧美精品中文字幕一区二区| 亚洲高清黄色| 日韩视频亚洲视频| 国产三级三级在线观看| 亚洲一区二区三区在线| 人妻av一区二区| 国产精品久久久一区二区| 欧美日韩综合网| jizzyou欧美16| 久久伊人精品视频| 不卡视频免费在线观看| 亚洲不卡av一区二区三区| v天堂中文在线| 日韩va欧美va亚洲va久久| 亚洲人一区二区| 亚洲视频一起| 欧美在线亚洲一区| 日本不卡视频| 精品裸体舞一区二区三区| 日韩欧美激情视频| 日本一区二区三区四区在线视频| 色91精品久久久久久久久| 精品91视频| 日韩视频在线播放| 日韩精品中文字幕一区二区 | a屁视频一区二区三区四区| 久久伊人精品一区二区三区| 日批视频免费播放| 欧美日韩亚洲不卡| 国产精品99re| 国产精品久久久久久亚洲毛片| 黄色片子免费看| 午夜一区不卡| 福利网在线观看| 亚洲国产网址| 95av在线视频| 日韩免费va| 九九久久综合网站| 美女毛片在线看| 欧美本精品男人aⅴ天堂| 一级片免费在线播放| 亚洲精选免费视频| 中文字幕在线看高清电影| 国产经典欧美精品| 婷婷六月天在线| 亚洲精品欧洲| 亚洲小说欧美另类激情| 亚洲区小说区| av资源一区二区| 日韩免费在线电影| 欧美有码在线视频| 超清av在线| 欧美精品一区二区免费| 东凛在线观看| 国产视频精品va久久久久久| a级片在线免费看| 欧美视频一区在线观看| 欧美福利视频一区二区| 亚洲精品乱码久久久久久黑人| 高清国产在线观看| 成人av手机在线观看| 欧美国产在线一区| 免费在线观看不卡| 国产成人久久777777| 亚洲高清网站| 日韩成人三级视频| 欧美1区2区3区| 正在播放一区二区三区| 精品美女视频| 欧美人与物videos另类| 国产伦理久久久久久妇女| 亚洲一区二区三| 亚洲人成777| 国产在线播放不卡| 97人人做人人爽香蕉精品| 日本国产欧美一区二区三区| eeuss鲁一区二区三区| 欧美另类在线播放| 国产淫片在线观看| 日韩中文字幕在线看| 91社区在线| 日韩一中文字幕| 日本电影全部在线观看网站视频| 中文字幕亚洲一区| 3d成人动漫在线| 最近2019年中文视频免费在线观看| 蜜桃视频在线入口www| 亚洲色图17p| 福利片在线看| 在线色欧美三级视频| 成人在线免费公开观看视频| 一本色道久久88精品综合| 国产三级在线看| 中文字幕综合一区| 麻豆影院在线| 精品中文字幕在线观看| 亚洲欧美成人影院| 国内精品一区二区三区| 日本在线高清| 国产精品免费一区豆花| 国产亚洲欧美日韩精品一区二区三区 | 亚洲美女喷白浆| 国产黄色免费在线观看| 色老头一区二区三区| 成码无人av片在线观看网站| 久精品免费视频| 黑森林国产精品av| 国产盗摄xxxx视频xxx69| 成人精品国产亚洲| 91视频免费网站| 大伊香蕉精品在线品播放| 久久免费一区| 日本道不卡免费一区| 亚洲色婷婷久久精品av蜜桃| 亚洲精品专区| jizz欧美激情18| 国产一区二区三区四| 无码人妻一区二区三区精品视频| 久久综合久久综合久久综合| 国产伦精品一区二区三区视频女| 国产精品福利一区| 国产精品成人久久| 欧美在线短视频| 亚洲经典一区二区| 亚洲欧美制服另类日韩| 高清免费电影在线观看| 午夜精品一区二区三区在线 | 日韩亚洲欧美在线| 亚洲 另类 春色 国产| 在线播放亚洲激情| 青草影视电视剧免费播放在线观看| 91av在线播放视频| 成人国产精品久久| 另类欧美小说| 一本一道久久a久久精品蜜桃| 欧美性久久久久| 国产在线不卡一区| 国产女主播喷水高潮网红在线| 亚洲四区在线观看| 久久久黄色大片| 日韩欧美成人激情| www.在线播放| 97在线精品国自产拍中文| а天堂中文最新一区二区三区| 免费久久99精品国产自| 欧美 日韩 国产一区二区在线视频| www.国产区| 成人av影院在线| 成人免费精品动漫网站| 91成人免费电影| 十八禁一区二区三区| 久久精品福利视频| 成人做爰视频www网站小优视频| 国产精品久久久久久久小唯西川| 色综合五月天| 欧美成人精品欧美一级乱| 国产成人在线视频网站| 日本裸体美女视频| 一本高清dvd不卡在线观看| 亚洲春色一区二区三区| 久久精品精品电影网| japanese23hdxxxx日韩| 久久久久免费网| 激情欧美日韩| 免费黄视频在线观看| 1024亚洲合集| 中文字字幕在线中文乱码| 亚洲一区第一页| 欧美7777| 欧美日韩亚洲一区二区三区在线观看 | 成人精品国产福利| 免费在线视频一区二区| 制服丝袜中文字幕亚洲| 日韩理伦片在线| 国产精品久久久久久五月尺| 精品一区亚洲| 国产免费一区二区三区视频| 99久久精品免费看国产| 久久丫精品久久丫| 精品日韩一区二区三区| 羞羞电影在线观看www| 亚洲一区亚洲二区| 综合国产在线| 在线观看免费看片| 一区二区三区在线视频免费 | 99久久精品国产一区| 在线免费观看毛片| 亚洲电影成人av99爱色| segui88久久综合9999| 韩日午夜在线资源一区二区| 一本色道久久| 色无极影院亚洲| 欧美日韩亚洲综合在线 | 91人成网站www| 91精品1区| 欧美人与性动交α欧美精品| 一区二区三区日韩欧美精品| 成人久久久精品国产乱码一区二区| 久久久免费在线观看| 欧美一区二区三区久久| 成人一级片网站| 国产精品久久福利| av一区二区三| 孩xxxx性bbbb欧美| 夜夜春成人影院| 日韩av卡一卡二| 樱花影视一区二区| 色wwwwww| 国产欧美一区二区三区四区| 91精品国产视频| 美女黄色一级视频| 在线区一区二视频| 免费高清在线观看| 国产精品一区二区a| 毛片一区二区| a在线视频播放观看免费观看| 337p日本欧洲亚洲大胆精品 | 欧美午夜精品一区二区三区| 日本激情视频在线观看| 风间由美久久久| 久久精品日韩欧美| 三级av在线免费观看| 亚洲国产又黄又爽女人高潮的| 欧美va在线观看| 五月天激情图片| 久久久激情视频| 国产suv一区二区| 2025国产精品视频| 国产精品97| 亚洲av无码一区二区三区观看 | 秋霞av国产精品一区| 国产精品久久久久久麻豆一区软件| 亚洲黄色小说在线观看| 91国内精品野花午夜精品| 在线观看的网站你懂的| 日本视频精品一区| 高清国产午夜精品久久久久久| 无码人妻丰满熟妇区五十路| 色综合天天综合网国产成人网| 精品国产a一区二区三区v免费| 女女调教被c哭捆绑喷水百合|