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

DDD 很難,推薦一套小白也能輕松落地的方案!

開發
本文我們按照 DDD 的分層原則詳細地落地了一個user添加和查詢功能,并實現支持多種持久化機制(MySQL 和 DynamoDB)的倉儲層設計。

DDD是微服務中經常用到的一種架構方式,在實際工作中,我們該如何快速落地一個 DDD工程呢?這篇文章,我們將手把手帶你落地一個 DDD項目,不管你有沒有 DDD經驗,都可以輕松使用。

在開始我們的文章之前,我們還是要簡單的了解下 DDD是什么,幫助我們下面更好地理解代碼工程。

一、什么是DDD?

DDD,全稱 Domain-Driven Design,翻譯為領域驅動設計,它是一種軟件開發方法論,由埃里克·埃文斯(Eric Evans) 在其2003年出版的同名書籍中提出。DDD旨在通過密切關注復雜軟件系統的核心業務領域,將業務需求與技術實現緊密結合,從而提高軟件的可維護性、可擴展性和靈活性。

1. DDD 的核心理念

DDD 以領域為核心,強調將業務領域作為軟件開發的核心,致力于深入理解業務需求和業務規則,通過建模來反映實際業務問題。

2. 統一語言

DDD使得開發團隊和業務專家共同使用的一種準確、一致的語言(Ubiquitous Language),用于描述業務領域中的概念、流程和規則,減少溝通障礙,提高理解一致性。

3. 戰略設計與戰術設計

DDD 分為戰略設計和戰術設計兩部分:

  • 戰略設計:關注整個系統的高層次結構和模塊劃分,定義不同的子域(Subdomain)和上下文邊界(Bounded Context)。
  • 戰術設計:關注特定上下文內的細節,實現領域模型和相關組件。

說實話,DDD的理論確實很燒腦,我們會在后續的文章中慢慢拆解。不管怎樣,在對 DDD有了簡單的了解之后,我們要進入今天的核心部分:DDD代碼實操。

本文目標:使用DDD + SpringBoot + JPA + 雙數據源(MySQL + DynamoDB)實現對 user表進行添加和查詢功能,完全適合小白操作。

二、項目整體結構

首先,我們先看下整個工程建的主要模塊以及模塊之間的依賴關系:

  • domain:核心領域模型和業務邏輯。
  • repository:倉儲接口定義。
  • application:應用服務層,協調領域對象和倉儲。
  • infrastructure:基礎設施層,包括具體的倉儲實現(MySQL 和 DynamoDB)、配置等。
  • config:獨立的配置模塊(可選,視項目復雜程度而定)。
  • api(或 web):入口層,如 REST API 控制器,主要處理外部接口請求。

模塊結構如下:

ddd-project/
├── build.gradle
├── settings.gradle
├── domain/
│   └── build.gradle
├── repository/
│   └── build.gradle
├── application/
│   └── build.gradle
├── infrastructure/
│   ├── build.gradle
│   ├── persistence-mysql/
│   │   └── build.gradle
│   └── persistence-dynamodb/
│       └── build.gradle
├── config/
│   └── build.gradle
└── api/
    └── build.gradle

三、項目模塊詳解

1. Gradle 配置

(1) 根項目 settings.gradle

在根項目的 settings.gradle 中,包含所有子模塊:

rootProject.name = 'ddd-project'

include 'domain'
include 'repository'
include 'application'
include 'infrastructure'
include 'infrastructure:persistence-mysql'
include 'infrastructure:persistence-dynamodb'
include 'config'
include 'api'

(2) 根項目 build.gradle

根項目的 build.gradle 通常用于定義全局的插件和依賴管理。

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.0' apply false
    id 'io.spring.dependency-management' version '1.1.0' apply false
}

allprojects {
    group = 'com.example'
    version = '1.0.0'
    
    repositories {
        mavenCentral()
    }
}

subprojects {
    apply plugin:'java'
    
    sourceCompatibility = '17'
    targetCompatibility = '17'

    dependencies {
        // 通用依賴,可以在此處添加
        implementation 'org.springframework.boot:spring-boot-starter'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }

    // 統一的測試任務配置等(可選)
}

2. 各子模塊配置

(1) domain 模塊

功能:定義核心領域模型和業務邏輯。

domain/build.gradle:

dependencies {
    // 無需依賴其他模塊,專注于領域邏輯
}

示例代碼:

// domain/src/main/java/com/example/domain/User.java
package com.example.domain;

publicclass User {
    private String id;
    private String name;
    private String email;

    // 構造函數、Getters 和 Setters

    public User() {}

    public User(String id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // getters and setters
    public String getId() {
        return id;
    }

    // ... 其他 getters 和 setters
}

(2) repository 模塊

功能:定義倉儲接口,供應用層和基礎設施層引用。

repository/build.gradle:

dependencies {
    implementation project(':domain')
}

示例代碼:

// repository/src/main/java/com/example/repository/UserRepository.java
package com.example.repository;

import com.example.domain.User;
import java.util.Optional;
import java.util.List;

public interface UserRepository {
    void save(User user);
    Optional<User> findById(String id);
}

(3) application 模塊

功能:實現應用服務,協調領域模型和倉儲接口。

application/build.gradle:

dependencies {
    implementation project(':domain')
    implementation project(':repository')
    implementation 'org.springframework.boot:spring-boot-starter'
}

示例代碼:

// application/src/main/java/com/example/application/UserService.java
package com.example.application;

import com.example.domain.User;
import com.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
publicclass UserService {

    privatefinal UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository){
        this.userRepository = userRepository;
    }

    public void createUser(User user){
        userRepository.save(user);
    }

    public Optional<User> getUserById(String id){
        return userRepository.findById(id);
    }
}

(4) infrastructure 模塊

功能:實現基礎設施組件,包括具體的倉儲實現。

infrastructure/build.gradle:

dependencies {
    implementation project(':repository')
    implementation 'org.springframework.boot:spring-boot-starter'
}

① infrastructure:persistence-mysql子模塊

功能:實現 MySQL 的具體倉儲。

infrastructure/persistence-mysql/build.gradle:

plugins {
    id 'org.springframework.boot'
    id 'io.spring.dependency-management'
}

dependencies {
    implementation project(':domain')
    implementation project(':repository')
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'mysql:mysql-connector-java'
    
    // 可選:MapStruct 用于對象映射
    implementation 'org.mapstruct:mapstruct:1.5.5.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
}

示例代碼:


// infrastructure/persistence-mysql/src/main/java/com/example/infrastructure/persistence/mysql/UserEntity.java
package com.example.infrastructure.persistence.mysql;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "users")
publicclass UserEntity {
    @Id
    private String id;
    private String name;
    private String email;

    // 構造函數、Getters 和 Setters

    public UserEntity() {}

    public UserEntity(String id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // getters and setters
}
// infrastructure/persistence-mysql/src/main/java/com/example/infrastructure/persistence/mysql/ JpaUserRepository.java
package com.example.infrastructure.persistence.mysql;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface JpaUserRepository extends JpaRepository<UserEntity, String> {
}
// infrastructure/persistence-mysql/src/main/java/com/example/infrastructure/persistence/mysql/MySQLUserRepository.java
package com.example.infrastructure.persistence.mysql;

import com.example.domain.User;
import com.example.repository.UserRepository;
import org.springframework.stereotype.Repository;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;
import java.util.List;
import java.util.stream.Collectors;

@Repository
publicclass MySQLUserRepository implements UserRepository {

    privatefinal JpaUserRepository jpaUserRepository;

    @Autowired
    public MySQLUserRepository(JpaUserRepository jpaUserRepository){
        this.jpaUserRepository = jpaUserRepository;
    }

    @Override
    public void save(User user) {
        UserEntity entity = new UserEntity(user.getId(), user.getName(), user.getEmail());
        jpaUserRepository.save(entity);
    }

    @Override
    public Optional<User> findById(String id) {
        Optional<UserEntity> entityOpt = jpaUserRepository.findById(id);
        return entityOpt.map(entity -> new User(entity.getId(), entity.getName(), entity.getEmail()));
    }
}

② infrastructure:persistence-dynamodb 子模塊

功能:實現 DynamoDB 的具體倉儲。

infrastructure/persistence-dynamodb/build.gradle:

plugins {
    id 'org.springframework.boot'
    id 'io.spring.dependency-management'
}

dependencies {
    implementation project(':domain')
    implementation project(':repository')
    implementation 'software.amazon.awssdk:dynamodb:2.20.0'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.0'
    implementation 'org.springframework.boot:spring-boot-starter'
}

示例代碼:

// infrastructure/persistence-dynamodb/src/main/java/com/example/infrastructure/persistence/dynamodb/DynamoDBUserRepository.java
package com.example.infrastructure.persistence.dynamodb;

import com.example.domain.User;
import com.example.repository.UserRepository;
import org.springframework.stereotype.Repository;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import org.springframework.beans.factory.annotation.Autowired;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Optional;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Repository
publicclass DynamoDBUserRepository implements UserRepository {

    privatestaticfinal String TABLE_NAME = "Users";

    privatefinal DynamoDbClient dynamoDbClient;
    privatefinal ObjectMapper objectMapper;

    @Autowired
    public DynamoDBUserRepository(DynamoDbClient dynamoDbClient){
        this.dynamoDbClient = dynamoDbClient;
        this.objectMapper = new ObjectMapper();
    }

    @Override
    public void save(User user) {
        try {
            String json = objectMapper.writeValueAsString(user);
            Map<String, Object> map = objectMapper.readValue(json, Map.class);
            Map<String, AttributeValue> item = map.entrySet().stream()
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            e -> AttributeValue.builder().s(e.getValue().toString()).build()
                    ));

            PutItemRequest request = PutItemRequest.builder()
                    .tableName(TABLE_NAME)
                    .item(item)
                    .build();

            dynamoDbClient.putItem(request);
        } catch (Exception e) {
            thrownew RuntimeException("Failed to save user to DynamoDB", e);
        }
    }

    @Override
    public Optional<User> findById(String id) {
        GetItemRequest request = GetItemRequest.builder()
                .tableName(TABLE_NAME)
                .key(Map.of("id", AttributeValue.builder().s(id).build()))
                .build();

        GetItemResponse response = dynamoDbClient.getItem(request);
        if (response.hasItem()) {
            try {
                String json = objectMapper.writeValueAsString(response.item());
                User user = objectMapper.readValue(json, User.class);
                return Optional.of(user);
            } catch (Exception e) {
                thrownew RuntimeException("Failed to parse user from DynamoDB", e);
            }
        }
        return Optional.empty();
    }
}

③ DynamoDB 客戶端配置

在 infrastructure:persistence-dynamodb 子模塊中配置 DynamoDB 客戶端 Bean。

// infrastructure/persistence-dynamodb/src/main/java/com/example/infrastructure/persistence/dynamodb/DynamoDBConfig.java
package com.example.infrastructure.persistence.dynamodb;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.regions.Region;

@Configuration
publicclass DynamoDBConfig {
    @Bean
    public DynamoDbClient dynamoDbClient() {
        return DynamoDbClient.builder()
                .region(Region.US_EAST_1) // 根據實際情況選擇區域
                .build();
    }
}

(5) config 模塊(可選)

功能:集中管理項目配置,例如選擇使用的倉儲實現、數據庫配置等。

config/build.gradle:

dependencies {
    implementation project(':application')
    implementation project(':infrastructure:persistence-mysql')
    implementation project(':infrastructure:persistence-dynamodb')
    implementation 'org.springframework.boot:spring-boot-starter'
}

示例代碼:

// config/src/main/java/com/example/config/RepositoryConfig.java
package com.example.config;

import com.example.repository.UserRepository;
import com.example.infrastructure.persistence_mysql.MySQLUserRepository;
import com.example.infrastructure.persistence_dynamodb.DynamoDBUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
publicclass RepositoryConfig {

    @Value("${app.repository.type}")
    private String repositoryType;

    privatefinal MySQLUserRepository mySQLUserRepository;
    privatefinal DynamoDBUserRepository dynamoDBUserRepository;

    @Autowired
    public RepositoryConfig(MySQLUserRepository mySQLUserRepository, DynamoDBUserRepository dynamoDBUserRepository){
        this.mySQLUserRepository = mySQLUserRepository;
        this.dynamoDBUserRepository = dynamoDBUserRepository;
    }

    @Bean
    public UserRepository userRepository() {
        if ("mysql".equalsIgnoreCase(repositoryType)) {
            return mySQLUserRepository;
        } elseif ("dynamodb".equalsIgnoreCase(repositoryType)) {
            return dynamoDBUserRepository;
        } else {
            thrownew IllegalArgumentException("Unsupported repository type: " + repositoryType);
        }
    }
}

**application.properties**(在 api 模塊或根模塊)

# application.properties
app.repository.type=mysql
# 或者
# app.repository.type=dynamodb

(6) api 模塊

功能:作為應用的入口,處理外部請求(如 REST API)。

api/build.gradle:

plugins {
    id 'org.springframework.boot'
    id 'io.spring.dependency-management'
}

dependencies {
    implementation project(':application')
    implementation project(':config')
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

示例代碼:

// api/src/main/java/com/example/api/UserController.java
package com.example.api;

import com.example.application.UserService;
import com.example.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/users")
publicclass UserController {

    privatefinal UserService userService;

    @Autowired
    public UserController(UserService userService){
        this.userService = userService;
    }

    @PostMapping
    public void createUser(@RequestBody User user){
        userService.createUser(user);
    }

    @GetMapping("/{id}")
    public Optional<User> getUserById(@PathVariable String id){
        return userService.getUserById(id);
    }
}

4. 模塊間依賴關系圖

domain
   ↑
repository
   ↑
application
   ↑
infrastructure
   ↑
config
   ↑
api
  • domain 是最底層,其他模塊依賴于它。
  • repository 依賴于 **domain**。
  • application 依賴于 repository 和 **domain**。
  • infrastructure 依賴于 repository 和 **domain**,實現具體倉儲。
  • config 依賴于 application 和 **infrastructure**,進行配置管理。
  • api 依賴于 application 和 **config**,作為應用入口。

四、實施步驟詳解

1. 創建各個模塊

使用 Gradle 命令或 IDE 創建各個模塊。例如,使用命令行:

mkdir ddd-project
cd ddd-project
gradle init --type basic
# 創建子模塊目錄
mkdir domain repository application infrastructure
mkdir infrastructure/persistence-mysql infrastructure/persistence-dynamodb
mkdir config api

然后,在各個子模塊目錄下創建相應的 build.gradle 文件并添加內容,如上所示。

2. 配置依賴關系

確保每個子模塊的 build.gradle 文件中正確地聲明依賴關系。例如,在 application 模塊的 build.gradle 中:

dependencies {
    implementation project(':domain')
    implementation project(':repository')
    implementation 'org.springframework.boot:spring-boot-starter'
}

類似地,在其他模塊中聲明所需的依賴。

3. 配置 SpringBoot

在 api 模塊中,添加 SpringBoot應用的主類:

// api/src/main/java/com/example/api/MyDddProjectApplication.java
package com.example.api;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = "com.example")
public class MyDddProjectApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyDddProjectApplication.class, args);
    }
}

說明:使用 @SpringBootApplication 注解并設置 scanBasePackages 為 com.example,確保 Spring 能掃描到所有子模塊中的組件。

4. 配置應用屬性

在 api 模塊中創建 src/main/resources/application.properties,并添加必要的配置:

# MySQL 配置
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=secret
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# 倉儲選擇
app.repository.type=mysql
# 或者
# app.repository.type=dynamodb

# DynamoDB 配置(如適用)
# aws.accessKeyId=YOUR_ACCESS_KEY
# aws.secretAccessKey=YOUR_SECRET_KEY
# aws.region=us-east-1

5. 構建和運行

在根項目目錄下,運行以下命令以構建和運行應用:

./gradlew build
./gradlew :api:bootRun

確保你的 MySQL 和 DynamoDB(如果選擇使用)都已正確配置和運行。

五、項目優化

1. 使用 Spring Profiles

為了更靈活地在不同環境(如開發、測試、生產)中選擇倉儲實現,可以使用 Spring Profiles。

示例:

在 MySQLUserRepository 和 DynamoDBUserRepository 上添加 @Profile 注解。

// MySQLUserRepository.java
@Repository
@Profile("mysql")
public class MySQLUserRepository implements UserRepository {
    // ...
}

// DynamoDBUserRepository.java
@Repository
@Profile("dynamodb")
public class DynamoDBUserRepository implements UserRepository {
    // ...
}

在 application.properties 中指定活躍配置:

spring.profiles.active=mysql
# 或者
# spring.profiles.active=dynamodb

2. 使用 MapStruct進行對象映射

手動在倉儲實現中轉換領域對象和持久化對象可能繁瑣,使用 MapStruct 可以簡化這一過程。

示例:

添加 MapStruct 依賴(已在 persistence-mysql 模塊中添加)。

定義映射接口:

// infrastructure/persistence-mysql/src/main/java/com/example/infrastructure/persistence/mysql/UserMapper.java
package com.example.infrastructure.persistence.mysql;

import com.example.domain.User;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserEntity toEntity(User user);
    User toDomain(UserEntity entity);
}

在 MySQLUserRepository 中使用 UserMapper 進行轉換:

// MySQLUserRepository.java
package com.example.infrastructure.persistence.mysql;

import com.example.domain.User;
import com.example.repository.UserRepository;
import org.springframework.stereotype.Repository;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;
import java.util.List;
import java.util.stream.Collectors;

@Repository
@Profile("mysql")
publicclass MySQLUserRepository implements UserRepository {

    privatefinal JpaUserRepository jpaUserRepository;
    privatefinal UserMapper userMapper = UserMapper.INSTANCE;

    @Autowired
    public MySQLUserRepository(JpaUserRepository jpaUserRepository){
        this.jpaUserRepository = jpaUserRepository;
    }

    @Override
    public void save(User user) {
        UserEntity entity = userMapper.toEntity(user);
        jpaUserRepository.save(entity);
    }

    @Override
    public Optional<User> findById(String id) {
        Optional<UserEntity> entityOpt = jpaUserRepository.findById(id);
        return entityOpt.map(userMapper::toDomain);
    }
}

3. 增加測試模塊

為每個模塊編寫單元測試和集成測試,確保各部分功能正常。

4. 使用依賴注入選擇倉儲實現

在 config 模塊中動態選擇倉儲實現,或使用工廠模式進一步封裝。

六、總結

本文,我們沒有講解 DDD那些燒腦的理論知識,而是按照 DDD 的分層原則詳細地落地了一個user添加和查詢功能,并實現支持多種持久化機制(MySQL 和 DynamoDB)的倉儲層設計。只要你有過 MVC 的 web開發經驗,應該可以快速理解上述 DDD的代碼工程。

對于 DDD模塊化設計帶來的好處,可以總結為以下幾點:

  • 高內聚、低耦合:每個模塊都有明確的職責,模塊之間通過接口進行通信,降低了耦合度。
  • 易于擴展:未來添加新的持久化機制(如 PostgreSQL、Redis 等)時,只需新增相應的基礎設施子模塊,實現倉儲接口即可。
  • 團隊協作:不同團隊或開發者可以并行開發不同模塊,減少沖突和依賴問題。
  • 可維護性:清晰的模塊邊界和職責分離,使得代碼更易于理解和維護。

在實際項目中,我們可根據具體的業務需求靈活地調整模塊劃分和依賴關系,確保架構設計既符合業務需求,又具備良好的技術基礎。

責任編輯:趙寧寧 來源: 猿java
相關推薦

2024-12-09 09:25:30

2019-02-20 10:22:20

監控HDFSHadoop

2025-03-03 10:00:00

2025-09-16 09:31:07

2025-07-07 04:22:00

2010-06-09 17:00:43

UML試題

2015-01-19 09:37:00

2014-12-17 12:46:17

華為存儲

2009-03-03 13:00:00

虛擬化技術vmwarexen

2022-07-10 20:45:47

React加載動畫庫

2023-03-22 23:23:25

React加載動畫庫

2018-08-02 09:44:35

AIOps實踐數據

2023-10-23 12:31:40

2018-07-25 18:44:35

智能硬件

2025-03-28 09:52:08

CIGo項目

2023-11-29 07:17:51

微信機器人AI

2009-06-23 18:01:45

Ajax框架源代碼

2018-08-31 08:42:48

LinuxUnix實用程序

2023-03-03 17:00:00

部署Linux內核

2014-12-02 10:02:21

Android異步任務
點贊
收藏

51CTO技術棧公眾號

国产羞羞视频在线播放| 性欧美一区二区三区| 国产精品密蕾丝视频下载| 欧美午夜影院在线视频| 亚洲电影免费| www.激情五月| 亚洲视频成人| 中文字幕亚洲字幕| 中文字幕一区二区三区乱码不卡| 在线观看爽视频| 亚洲日本在线天堂| 九九九九精品九九九九| 中文字幕+乱码+中文乱码www| 一区二区三区在线电影| 精品一区电影国产| 国产农村妇女精品久久| 涩涩涩视频在线观看| 国产精品久久久久久福利一牛影视 | 91精品国产综合久久精品麻豆| 国产男女免费视频| 色哟哟免费在线观看 | 99精彩视频在线观看免费| 国产黄色片免费看| 午夜视频一区| 在线午夜精品自拍| 国产高清成人久久| 国产精久久久| 欧美日韩中文字幕一区| 韩国日本在线视频| 黄色污污视频在线观看| 国产精品久久久久久亚洲毛片| 国语精品免费视频| 精品国自产拍在线观看| 精品亚洲aⅴ乱码一区二区三区| 97免费中文视频在线观看| 亚洲xxxx3d动漫| 成人一区二区| 一区二区中文字幕| 自拍偷拍亚洲天堂| 久久人人爽人人爽人人片av不| 欧美一区二区二区| 99精品视频国产| 国产精品99久久久久久董美香| 日韩欧美国产一区二区| 日韩xxxx视频| 丁香花视频在线观看| 国产一级大片在线观看| 色狠狠久久av综合| 精品88久久久久88久久久 | 久久99最新地址| 国产成人综合精品| 无码人妻丰满熟妇奶水区码| 国产午夜精品一区二区三区欧美 | 亚洲综合网在线| 91麻豆国产自产在线观看亚洲| 亚洲精品综合精品自拍| 免费黄色三级网站| 精品视频自拍| 日韩国产一区三区| 朝桐光av一区二区三区| 欧美freesex8一10精品| 亚洲国产婷婷香蕉久久久久久| 色悠悠在线视频| silk一区二区三区精品视频| 亚洲精品在线免费观看视频| 天天躁日日躁狠狠躁av麻豆男男| 国产一级成人av| 日韩国产高清视频在线| 大黑人交xxx极品hd| 亚洲第一福利专区| 亚洲天堂第二页| 极品蜜桃臀肥臀-x88av| 日韩在线观看一区 | 多男操一女视频| 天天射综合网视频| 欧美人与性动交a欧美精品| 久久香蕉精品视频| 国产一区二区精品| 国产精品久久久久久久久久三级| 在线观看免费视频a| 精品一区二区成人精品| 电影午夜精品一区二区三区 | 粉嫩13p一区二区三区| 国产欧美韩日| 国产大学生校花援交在线播放| 欧美激情一区二区三区| 男同互操gay射视频在线看| 久久国产精品黑丝| 色天天综合色天天久久| 57pao国产成永久免费视频| 视频欧美一区| 亚洲欧美日韩爽爽影院| 国产精品白丝喷水在线观看| 亚洲第一黄网| 国产剧情日韩欧美| 亚洲精品字幕在线| 国产亚洲va综合人人澡精品| 亚洲色图都市激情| 国模套图日韩精品一区二区| 51精品国自产在线| 99久久人妻精品免费二区| 国产在视频线精品视频www666| 久久精品国产96久久久香蕉| 亚洲精品视频在线观看免费视频| 人人精品人人爱| 国产精品手机视频| 婷婷激情在线| 欧美日韩免费网站| 色悠悠久久综合网| 精品淫伦v久久水蜜桃| 色婷婷av一区二区三区在线观看| 国产精品2020| 久久精品国产99国产| 激情小说综合区| 日本天堂在线观看| 91国内精品野花午夜精品| 国产精品嫩草69影院| 久久国产电影| 国产91久久婷婷一区二区| 国产wwwxxx| 中文字幕精品—区二区四季| 久在线观看视频| 一区二区三区国产好| 亚洲视频视频在线| 黄色一级片免费看| 国产成人综合亚洲91猫咪| 亚洲va久久久噜噜噜久久狠狠 | 国产精品十八以下禁看| 免费av网站观看| 综合久久久久久久| 午夜国产一区二区三区| 亚洲伊人春色| 91精品国产一区| 亚洲第一页综合| 亚洲乱码国产乱码精品精可以看| www.com操| 国内成人自拍| 国产成人黄色av| 飘雪影院手机免费高清版在线观看 | 综合另类专区| 亚洲国产精品99| 精品午夜福利在线观看| 国产精品白丝av| 国产四区在线观看| 亚洲资源在线| 日日狠狠久久偷偷四色综合免费 | 欧美日韩亚洲一区二区三区四区| 丁香影院在线| 精品久久久久久亚洲综合网| 激情五月少妇a| 国产毛片精品视频| 成年人三级视频| 日韩精品一区二区三区中文| 欧美床上激情在线观看| 国内精品国产成人国产三级| 一区二区三区四区激情| 欧美熟妇精品一区二区| 欧美视频官网| 国产青春久久久国产毛片| 成人av影院在线观看| 亚洲国产精久久久久久| 四虎成人永久免费视频| 久久久高清一区二区三区| 毛葺葺老太做受视频| 欧美亚洲国产激情| 成人精品久久一区二区三区| 国产美女福利在线| 日韩精品一区二区三区视频在线观看| 久久久久亚洲AV| 91女厕偷拍女厕偷拍高清| 欧美v在线观看| 欧美在线电影| 92看片淫黄大片看国产片| 伊人春色在线观看| 亚洲精品97久久| wwwwww在线观看| 亚洲美女屁股眼交3| 欧美图片自拍偷拍| 男人天堂欧美日韩| 亚洲三级一区| 91久久精品无嫩草影院| 欧美一级电影在线| 最新97超碰在线| 日韩欧美国产成人一区二区| 国产无人区码熟妇毛片多| 亚洲国产精品二十页| 国产黑丝在线视频| 久久国产66| 中文字幕黄色大片| 日韩理论电影中文字幕| 国产欧美日韩91| 草草视频在线| 伊人久久五月天| 亚洲av无码乱码国产麻豆 | 欧美激情欧美激情| 精品电影在线| 日韩一区二区三区四区| 日本高清不卡码| 亚洲丝袜美腿综合| 国产亚洲色婷婷久久99精品91| 欧美a一区二区| 久久在线中文字幕| 日韩综合一区| 久久久久久99| 天堂精品久久久久| 国产精品美女久久| 国产在线精彩视频| 大胆欧美人体视频| jizz日韩| 日韩电影大全免费观看2023年上| 一级黄色片视频| 色偷偷久久一区二区三区| 黄页网站免费观看| 中文字幕亚洲区| 精品人妻无码一区二区三区| 国产成人鲁色资源国产91色综| 欧美精品aaaa| 国产色综合网| 真人抽搐一进一出视频| 99精品在线免费在线观看| 欧美专区一二三| 加勒比久久高清| 亚洲综合日韩在线| 亚洲二区av| 国产精品久久久久久久久免费看| 亚洲伊人av| 午夜精品福利视频| 神马午夜伦理不卡| 久久视频国产精品免费视频在线 | 国产日产亚洲精品系列| 中文乱码人妻一区二区三区视频| 成人免费毛片高清视频| 日本少妇激三级做爰在线| 免费成人美女在线观看| 午夜dv内射一区二区| 亚洲专区免费| 欧美日韩黄色一级片| 精品二区视频| 久久99久久99精品| 亚洲一本视频| 国产色一区二区三区| 极品av少妇一区二区| 无码人妻精品一区二区蜜桃网站| 中文精品久久| 超碰在线免费观看97| 97精品国产福利一区二区三区| 亚洲成人在线视频网站| 欧美天天综合| 在线不卡日本| 国产精品久久久久久麻豆一区软件 | 日韩欧美1区| 亚洲一区二区三区午夜| 日韩理论电影大全| 一区在线电影| 在线精品国产| 国产免费裸体视频| 亚洲国产精品第一区二区| 国产男女免费视频| 久久国产日韩| 欧美三级理论片| 精品一二三四区| 人妻精品久久久久中文字幕69| 国产成人午夜精品5599| 国产人妻精品午夜福利免费| av一区二区久久| 自拍偷拍中文字幕| 中文字幕av一区二区三区高| 亚洲熟女毛茸茸| 一二三四社区欧美黄| 日本五十路女优| 一本大道av一区二区在线播放| 亚洲图片欧美日韩| 欧美精品自拍偷拍| 亚洲精品久久久蜜桃动漫| 亚洲精品美女在线观看| 国产福利在线| 欧美久久精品一级黑人c片 | 天天av天天翘天天综合网| av毛片在线免费观看| 欧美日韩免费在线视频| 亚洲国产精品suv| 亚洲男人7777| 蜜桃视频网站在线| 久久久久久久久久久网站| 欧洲一区二区三区精品| 91九色国产社区在线观看| 国产精品毛片av| 亚洲精品乱码视频| 亚洲一本视频| 亚洲欧美自拍另类日韩| 成人sese在线| 长河落日免费高清观看| 亚洲一区电影777| 国产情侣免费视频| 精品欧美一区二区三区精品久久| 日本福利片高清在线观看| 日韩视频一区在线| 丝袜老师在线| **亚洲第一综合导航网站| 曰本一区二区三区视频| 18视频在线观看娇喘| 久久久久久久尹人综合网亚洲| 亚洲免费在线播放视频| 久久久99精品久久| 久久久久久久久久久久久久免费看 | 亚洲 国产 日韩 欧美| 精品国产一区二区三区久久久蜜月| 蝌蚪视频在线播放| 欧美国产第一页| 欧美成人一二区| 欧美人与性禽动交精品| 亚洲午夜黄色| 欧美精品 - 色网| 国产欧美日韩不卡免费| 日韩成人免费在线视频| 欧美一级片在线观看| 999在线视频| 日韩av免费看| 欧美久久精品| 国产精品久久久久久久乖乖| 精品一区二区三区免费毛片爱 | 91国偷自产一区二区三区的观看方式| 图片一区二区| 日韩精品伦理第一区| 国产亚洲欧洲| 国产精品一区二区无码对白| 亚洲免费av在线| 91福利免费视频| 中文欧美日本在线资源| 色8久久影院午夜场| 久久人人爽爽人人爽人人片av| 午夜精品久久| 麻豆精品国产传媒| 亚洲卡通动漫在线| 国产欧美一级片| www.国产一区| 亚洲精品自拍| 一区二区日本伦理| 久久精品国产一区二区三区免费看| 精品无码人妻一区二区免费蜜桃| 岛国av在线不卡| 色在线免费视频| 97精品国产97久久久久久| 老牛精品亚洲成av人片| 免费无码毛片一区二三区| 成人性生交大片免费看视频在线| 国产一级淫片免费| 欧美精品一区二区精品网| 精精国产xxxx视频在线中文版| 97久久夜色精品国产九色| 欧美日韩成人| 日本少妇xxxx| 色综合天天综合在线视频| 美国成人毛片| 国产精品大陆在线观看| 日韩综合在线| 国产成人精品综合久久久久99 | 国产精品自拍片| 91在线视频官网| 亚洲第一网站在线观看| 在线精品播放av| 四虎国产精品免费久久5151| 红桃一区二区三区| 成人av免费在线播放| 国内自拍视频在线播放| 在线观看亚洲区| 亚洲国产欧美国产第一区| 91精品国产91久久久久麻豆 主演| 99re这里都是精品| 97人妻一区二区精品视频| 日韩亚洲国产中文字幕| 136导航精品福利| 国产日产欧美视频| 中文字幕av一区二区三区高| 国产99999| 欧美孕妇孕交黑巨大网站| 日韩专区精品| 亚洲乱妇老熟女爽到高潮的片| 欧美性高潮在线| 天堂地址在线www| 国产精品午夜av在线| 日韩电影一区二区三区四区| 极品盗摄国产盗摄合集| 国产丝袜一区二区三区| 99久久999| 欧美日韩在线一| 最新热久久免费视频| 亚洲欧美日本在线观看| 成人在线播放av| 日韩视频二区| 女同久久另类69精品国产| 亚洲国产成人精品一区二区| 欧美日韩女优| 亚洲人成无码网站久久99热国产| 你懂的在线观看| 欧美性猛交xxxx| 91精品国产综合久久久久久豆腐| 亚洲自拍小视频免费观看| 亚欧成人精品| 日韩黄色免费观看|