精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

天海翼在线视频| 亚洲国产cao| 日韩欧美有码在线| 国产在线精品播放| 国产精品jizz| 第一av在线| 中文乱码免费一区二区三区下载| 久久综合狠狠综合久久综合88 | 亚洲精品女av网站| 黄色aaa视频| 深夜福利视频一区二区| 国产精品一区一区三区| 中文字幕亚洲二区| 五月婷婷激情久久| 国产黄在线看| 视频一区二区三区中文字幕| 亚洲国产高潮在线观看| 一本久道高清无码视频| www.黄色片| 欧美福利在线| 日韩美一区二区三区| 日本老太婆做爰视频| 国产日韩欧美视频在线观看| 亚洲国产精品久久久天堂| 欧美日韩成人综合在线一区二区| 四虎永久国产精品| 中文字幕日产av| 99精品综合| 欧美一区二区黄| 大胆欧美熟妇xx| 欧美一区二区公司| 99精品热6080yy久久| 亚洲第一级黄色片| 亚洲一区日韩精品| 成人在线观看亚洲| 国产成人精品aa毛片| 欧美精品精品精品精品免费| 欧美图片自拍偷拍| av剧情在线观看| xnxx国产精品| 国产精品白丝jk喷水视频一区| 九九九视频在线观看| 日韩一级特黄| 一区二区激情视频| 久久99久久99精品蜜柚传媒| 潘金莲一级淫片aaaaaa播放| 欧美www视频在线观看| 日韩一级片在线观看| av免费观看国产| 久久久久国产精品嫩草影院| 国内综合精品午夜久久资源| 亚洲国产天堂久久国产91 | 免费看电影在线| 99久久婷婷国产精品综合| 日本高清不卡在线| 久久爱一区二区| 色偷偷综合网| 亚洲国产福利在线| 熟妇高潮一区二区| 成人精品国产亚洲| 亚洲成av人片一区二区三区| 欧洲国产精品| www.日韩高清| 国产成人在线视频网站| 日本欧美爱爱爱| 激情综合网五月天| 欧美少妇xxxx| 亚洲韩国日本中文字幕| 91丝袜在线观看| 999精品视频在线观看| 天天操天天色综合| 中文字幕在线亚洲精品| 婷婷综合激情网| 日韩激情在线观看| 欧美黄网免费在线观看| 日本午夜精品视频| 偷窥自拍亚洲色图精选| 91麻豆精品国产无毒不卡在线观看| 国产一区二区网| 高潮毛片在线观看| 亚洲第一精品在线| 成人观看免费完整观看| 欧美野外wwwxxx| 午夜激情久久久| 久久久久久久少妇| 悠悠资源网亚洲青| 亚洲一区二区高清| 日本黄色a视频| 国产乱子伦三级在线播放| 国产精品每日更新在线播放网址| 久久99精品久久久久久久久久| 日本大臀精品| 91年精品国产| 亚洲一区二区三区乱码| 青梅竹马是消防员在线| 国产精品久久久久久久久晋中| 欧美不卡三区| 五月婷婷免费视频| 国产精品美女久久久久久| 日韩精品在线观看av| 美女一区网站| 欧美小视频在线观看| 尤物国产在线观看| 亚洲人成网站77777在线观看 | 理论片中文字幕| 国产一区在线观看麻豆| 国产精品综合不卡av| 亚洲第一网站在线观看| 国产一区二区91| 欧美日本韩国一区二区三区| 四虎在线免费观看| www.色精品| 在线电影看在线一区二区三区| 国产啊啊啊视频在线观看| 一本大道综合伊人精品热热| 成人观看免费完整观看| 深夜福利一区二区三区| 精品美女被调教视频大全网站| 日本黄色www| 亚洲综合影院| 亚洲激情小视频| 精品无码一区二区三区蜜臀| 久久精品国语| 国产精品久久99久久| 老牛影视av牛牛影视av| 亚洲欧美国产三级| 成人免费网站入口| 先锋影音一区二区| 亚洲一品av免费观看| 日韩视频在线观看免费视频| 99在线观看免费视频精品观看| 91精品视频播放| 国产自产一区二区| 亚洲人成网站影音先锋播放| 800av在线免费观看| 欧美日韩破处视频| 日韩女优制服丝袜电影| 国产精品理论在线| 视频在线观看国产精品| 麻豆亚洲一区| 特黄毛片在线观看| 国产婷婷成人久久av免费高清| xxx在线播放| 国产精品久久久久毛片大屁完整版| 欧美一区第一页| 性高潮视频在线观看| 国产尤物一区二区在线| 日韩在线电影一区| 在线黄色网页| 日韩欧美在线第一页| 国产老熟女伦老熟妇露脸| 欧美视频网址| 国产精品久久久久久影视| 国产理论片在线观看| 本田岬高潮一区二区三区| 欧洲成人一区二区| 国产成人精品亚洲日本在线观看| 欧美精品aⅴ在线视频| 在线天堂www在线国语对白| 国一区二区在线观看| 国产成人一区二区三区免费看| 高清福利在线观看| 一本色道久久综合亚洲精品按摩| 欧美图片第一页| 免费高清在线一区| 国产一区二区三区黄| 99中文字幕一区| 天天影视网天天综合色在线播放| 欧美一区二区免费在线观看| 亚洲影院免费| 成人午夜电影免费在线观看| 蜜乳av一区| 亚洲激情第一页| 天堂免费在线视频| 不卡av免费在线观看| 成人综合视频在线| 日本在线成人| 午夜精品理论片| 国产日韩免费视频| 亚洲第一福利视频在线| 国产手机在线观看| 国产乱码一区二区三区| 亚洲熟妇国产熟妇肥婆| 911亚洲精品| 日本免费在线精品| 国产剧情在线| 精品视频一区二区三区免费| av网在线播放| 国产精品最新自拍| 亚洲欧洲一区二区福利| 在线日韩影院| 精品国产一区二区三区久久| 精品国产www| 一区二区三区.www| 国产jjizz一区二区三区视频| 精一区二区三区| 婷婷四房综合激情五月| 日韩精品成人在线观看| 国产99久久精品一区二区| a篇片在线观看网站| 亚洲免费av电影| 日本特级黄色片| 91色视频在线| 中文字幕亚洲影院| 国产精品精品国产一区二区| 国产综合 伊人色| 久久精品九色| 欧美大片va欧美在线播放| 国产免费黄色录像| 色天天综合久久久久综合片| 欧美特黄一区二区三区| 国产高清成人在线| 久热精品在线观看视频| 9色精品在线| 亚洲色婷婷久久精品av蜜桃| 国产在线不卡一区二区三区| 成年无码av片在线| 亚洲av无码一区二区三区性色| 一区二区三区四区不卡在线 | 一区二区三区四区视频在线| 欧美人妖视频| 欧洲美女免费图片一区| 七七成人影院| 蜜臀久久99精品久久久无需会员 | 精品国产乱码久久久久久婷婷| 2025国产精品自拍| 国产福利精品一区| 欧美日韩在线观看不卡| 性一交一乱一区二区洋洋av| 韩日视频在线观看| 亚洲欧美伊人| 日本精品免费视频| 99久久婷婷国产综合精品青牛牛| 久久久噜噜噜久久久| 黑人精品一区二区| 日韩一级完整毛片| 国产成人精品白浆久久69| 亚洲高清一区二区三区| 丁香花五月激情| av在线不卡免费看| zjzjzjzjzj亚洲女人| 国产高清在线观看免费不卡| 亚洲国产午夜精品| 亚洲区国产区| 日韩精品一区二区三区丰满 | 日韩精品福利在线| 日本中文字幕久久| 亚洲欧美综合网| 美女久久久久久久久| 国产精品 欧美精品| 亚洲精品一二三四| 国产成人精品亚洲日本在线桃色 | 国产精品中文| 91亚洲精品丁香在线观看| 精精国产xxxx视频在线野外| 亚洲视频在线观看免费| 国产日产亚洲系列最新| 欧美一级在线免费| 性一交一乱一精一晶| 精品国产乱码久久久久久夜甘婷婷| 激情视频网站在线观看| 色猫猫国产区一区二在线视频| 国产乱码77777777| 欧美日韩精品欧美日韩精品| 国产女人爽到高潮a毛片| 日韩天堂在线观看| 少妇一级淫片免费看| 亚洲男人第一av网站| www.视频在线.com| 日韩国产精品视频| 欧美色综合一区二区三区| 国产亚洲美女精品久久久| 2019中文字幕在线视频| 久久久999精品视频| 久久经典视频| 久久国内精品一国内精品| 丝袜中文在线| 久久久精品美女| av网站免费在线看| 日本一区二区高清不卡| 亚洲午夜在线观看| 欧美亚韩一区| 亚洲一区综合| 国产一区欧美| www.日日操| 国产成人在线观看免费网站| 国产亚洲色婷婷久久99精品91| 国产日韩在线不卡| 国产亚洲无码精品| 成人免费视频网站在线观看| 亚洲无在线观看| 成人精品亚洲人成在线| 在线观看日本中文字幕| 亚洲男人的天堂在线观看| 久久夜色精品亚洲| 亚洲国产日韩a在线播放| 日本视频网站在线观看| 日韩一区二区三区四区五区六区| 香蕉视频黄色片| x99av成人免费| 在线观看的黄色| 91久久精品一区二区别| av资源久久| 视频在线99re| 亚洲人体大胆视频| 做a视频在线观看| 91麻豆免费视频| 97免费视频在线| heyzo中文字幕在线| 国产精品久久久久久久久久99| 风间由美一区二区av101| av成人午夜| 在线日韩成人| 亚洲欧美电影在线观看| 日韩午夜高潮| 91成人在线观看喷潮蘑菇| 国产精品亚洲视频| 波多野结衣av在线观看| 亚洲香肠在线观看| 国产精品久久综合青草亚洲AV| 亚洲天堂影视av| 17videosex性欧美| 亚洲jizzjizz日本少妇| 成人激情视频| 黄www在线观看| av电影在线观看完整版一区二区| 翔田千里88av中文字幕| 欧美性色黄大片| 国产又粗又猛又爽又黄的视频一| 亚洲欧美国产va在线影院| 国产盗摄一区二区| 97人人澡人人爽| 自拍日韩欧美| 蜜桃福利午夜精品一区| 亚洲国产高清aⅴ视频| 国产18无套直看片| 色婷婷精品大视频在线蜜桃视频 | 亚洲国产精品成人精品| 18网站在线观看| 91久久嫩草影院一区二区| 99久久夜色精品国产亚洲1000部| 久热精品在线播放| 国产精品蜜臀av| 亚洲一级黄色大片| 精品国产第一区二区三区观看体验| 黄色网在线免费看| 91色视频在线观看| 在线观看日韩| 2025中文字幕| 亚洲成人激情av| 天天操天天爱天天干| 欧美亚洲视频一区二区| 伊人久久综合影院| 色一情一乱一伦一区二区三区日本| 久久综合给合久久狠狠狠97色69| 免费av网站在线| 一区二区三区久久精品| 欧美大胆的人体xxxx| 91一区二区三区| 亚洲区第一页| 欧美黄色一级生活片| 欧美亚洲国产一区二区三区| 日本美女在线中文版| 4p变态网欧美系列| 伊人成综合网yiren22| 另类小说第一页| 大桥未久av一区二区三区中文| 久久老司机精品视频| 欧美日韩中文另类| 国产精品久久久久久福利| 91九色极品视频| 99在线精品视频在线观看| 天天躁日日躁aaaxxⅹ | 激情五月婷婷久久| 国产精品亲子伦对白| 99久久久无码国产精品免费| 久久久久久美女| 久久综合影院| 欧美 日本 亚洲| 国产色产综合产在线视频| ,一级淫片a看免费| 国产亚洲精品美女久久久久| 欧美一级做a| 日本精品久久久久久久久久| 久久久久久麻豆| 日本中文字幕在线免费观看| 亚洲人成啪啪网站| 久久久精品区| 欧美性久久久久| 亚洲精品免费视频| 邻家有女韩剧在线观看国语| 91色琪琪电影亚洲精品久久| 99国产精品久久久久久久| 99久久99久久精品免费看小说.| 日韩一区二区视频| 欧美aaa大片视频一二区| 欧美精品中文字幕一区二区| 精品一二三四在线| 91视频免费看片| 亚洲成色www8888|