joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

以下是对 Spring Boot 项目目录结构及分层(包含 DAODTO)的简洁总结,重新整理后更清晰明了:


1. 典型 Spring Boot 项目目录结构

my-spring-boot-project/
├── src/
│   ├── main/
│   │   ├── java/com/example/myapp/
│   │   │   ├── Application.java       # 主入口类
│   │   │   ├── controller/           # 控制器层(处理请求)
│   │   │   │   └── MyController.java
│   │   │   ├── service/             # 服务层(业务逻辑)
│   │   │   │   ├── MyService.java   # 接口
│   │   │   │   └── impl/MyServiceImpl.java
│   │   │   ├── dao/                 # 数据访问层(DAO)
│   │   │   │   └── MyDao.java
│   │   │   ├── entity/              # 实体类(数据库映射)
│   │   │   │   └── MyEntity.java
│   │   │   ├── dto/                 # 数据传输对象
│   │   │   │   ├── MyRequestDto.java  # 请求 DTO
│   │   │   │   └── MyResponseDto.java # 响应 DTO
│   │   │   ├── config/              # 配置类
│   │   │   └── util/                # 工具类
│   │   └── resources/
│   │       ├── application.properties # 配置文件
│   │       ├── static/               # 静态资源
│   │       └── templates/            # 模板文件
│   └── test/                         # 测试代码和资源
├── pom.xml                           # Maven 构建文件
└── README.md                         # 项目说明

2. 各层作用及 DTO 的意义

  1. controller/ - 控制器层

    • 处理 HTTP 请求,返回响应。
    • 使用 DTO(如 MyRequestDtoMyResponseDto)接收和返回数据。
  2. service/ - 服务层

    • 处理业务逻辑,调用 DAO,负责 DTOEntity 的转换。
    • 通常包含接口和实现类。
  3. dao/ - 数据访问层

    • 与数据库交互,执行 CRUD 操作。
    • 在 Spring Data JPA 中常用 repository/ 替代,但功能一致。
  4. entity/ - 实体层

    • 数据库表的映射类(如 @Entity),用于持久化。
  5. dto/ - 数据传输对象

    • 用于层间数据传递,隔离 Entity,定制字段。
    • 示例:MyRequestDto(请求数据)、MyResponseDto(响应数据)。

3. 数据流转

  • 请求: 用户 → Controller(接收 MyRequestDto)→ Service(转为 MyEntity)→ DAO(保存到数据库)。
  • 响应: DAO(返回 MyEntity)→ Service(转为 MyResponseDto)→ Controller(返回给用户)。

4. 关键点

  • DAO vs Repository: DAO 是传统术语,Repository 是 Spring Data 的抽象,作用相同。
  • 为什么用 DTO: 保护 Entity,灵活定制数据,避免直接暴露数据库结构。
  • 转换: EntityDTO 之间通常用手动映射或工具(如 MapStruct)转换。

这个结构适用于大多数 Spring Boot 项目,尤其是 REST API 类型。

curd demo

下面是一个基于上述 Spring Boot 项目结构的 CRUD(Create, Update, Read, Delete)示例,使用 Spring Data JPA 实现。我们以一个简单的“用户”(User)管理为例,展示各层的代码。


1. 项目目录结构

my-spring-boot-project/
├── src/
│   ├── main/
│   │   ├── java/com/example/myapp/
│   │   │   ├── Application.java
│   │   │   ├── controller/
│   │   │   │   └── UserController.java
│   │   │   ├── service/
│   │   │   │   ├── UserService.java
│   │   │   │   └── impl/UserServiceImpl.java
│   │   │   ├── dao/
│   │   │   │   └── UserDao.java
│   │   │   ├── entity/
│   │   │   │   └── User.java
│   │   │   ├── dto/
│   │   │   │   ├── UserRequestDto.java
│   │   │   │   └── UserResponseDto.java
│   │   └── resources/
│   │       └── application.properties
├── pom.xml

2. 代码实现

2.1 pom.xml

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-spring-boot-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
</project>

2.2 Application.java

package com.example.myapp;

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

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

2.3 entity/User.java

package com.example.myapp.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private int age;

    // Constructors
    public User() {}
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}

2.4 dto/UserRequestDto.java

package com.example.myapp.dto;

public class UserRequestDto {
    private String name;
    private int age;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}

2.5 dto/UserResponseDto.java

package com.example.myapp.dto;

public class UserResponseDto {
    private Long id;
    private String name;
    private int age;

    public UserResponseDto(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // Getters
    public Long getId() { return id; }
    public String getName() { return name; }
    public int getAge() { return age; }
}

2.6 dao/UserDao.java

package com.example.myapp.dao;

import com.example.myapp.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserDao extends JpaRepository<User, Long> {
}

2.7 service/UserService.java

package com.example.myapp.service;

import com.example.myapp.dto.UserRequestDto;
import com.example.myapp.dto.UserResponseDto;

import java.util.List;

public interface UserService {
    UserResponseDto createUser(UserRequestDto requestDto);
    UserResponseDto getUser(Long id);
    List<UserResponseDto> getAllUsers();
    UserResponseDto updateUser(Long id, UserRequestDto requestDto);
    void deleteUser(Long id);
}

2.8 service/impl/UserServiceImpl.java

package com.example.myapp.service.impl;

import com.example.myapp.dao.UserDao;
import com.example.myapp.dto.UserRequestDto;
import com.example.myapp.dto.UserResponseDto;
import com.example.myapp.entity.User;
import com.example.myapp.service.UserService;
import org.springframework.stereotype.Service;

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

@Service
public class UserServiceImpl implements UserService {
    private final UserDao userDao;

    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public UserResponseDto createUser(UserRequestDto requestDto) {
        User user = new User(requestDto.getName(), requestDto.getAge());
        user = userDao.save(user);
        return new UserResponseDto(user.getId(), user.getName(), user.getAge());
    }

    @Override
    public UserResponseDto getUser(Long id) {
        User user = userDao.findById(id)
                .orElseThrow(() -> new RuntimeException("User not found"));
        return new UserResponseDto(user.getId(), user.getName(), user.getAge());
    }

    @Override
    public List<UserResponseDto> getAllUsers() {
        return userDao.findAll().stream()
                .map(user -> new UserResponseDto(user.getId(), user.getName(), user.getAge()))
                .collect(Collectors.toList());
    }

    @Override
    public UserResponseDto updateUser(Long id, UserRequestDto requestDto) {
        User user = userDao.findById(id)
                .orElseThrow(() -> new RuntimeException("User not found"));
        user.setName(requestDto.getName());
        user.setAge(requestDto.getAge());
        user = userDao.save(user);
        return new UserResponseDto(user.getId(), user.getName(), user.getAge());
    }

    @Override
    public void deleteUser(Long id) {
        userDao.deleteById(id);
    }
}

2.9 controller/UserController.java

package com.example.myapp.controller;

import com.example.myapp.dto.UserRequestDto;
import com.example.myapp.dto.UserResponseDto;
import com.example.myapp.service.UserService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;

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

    @PostMapping
    public UserResponseDto createUser(@RequestBody UserRequestDto requestDto) {
        return userService.createUser(requestDto);
    }

    @GetMapping("/{id}")
    public UserResponseDto getUser(@PathVariable Long id) {
        return userService.getUser(id);
    }

    @GetMapping
    public List<UserResponseDto> getAllUsers() {
        return userService.getAllUsers();
    }

    @PutMapping("/{id}")
    public UserResponseDto updateUser(@PathVariable Long id, @RequestBody UserRequestDto requestDto) {
        return userService.updateUser(id, requestDto);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
}

2.10 resources/application.properties

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
server.port=8080

3. 使用说明

  1. 运行项目: 启动 Application.java,访问 http://localhost:8080/h2-console 查看 H2 数据库。
  2. 测试 API:
    • 创建用户: POST /api/users
      请求: {"name": "Alice", "age": 25}
      响应: {"id": 1, "name": "Alice", "age": 25}
    • 查询用户: GET /api/users/1
      响应: {"id": 1, "name": "Alice", "age": 25}
    • 查询所有用户: GET /api/users
      响应: [{"id": 1, "name": "Alice", "age": 25}]
    • 更新用户: PUT /api/users/1
      请求: {"name": "Alice Updated", "age": 26}
      响应: {"id": 1, "name": "Alice Updated", "age": 26}
    • 删除用户: DELETE /api/users/1

4. 总结

  • Entity: User 表示数据库表结构。
  • DTO: UserRequestDtoUserResponseDto 用于请求和响应,避免直接暴露 Entity
  • DAO: UserDao 使用 Spring Data JPA 提供 CRUD 方法。
  • Service: UserServiceImpl 处理逻辑,转换 EntityDTO
  • Controller: UserController 提供 REST API。

这个示例是完整的 CRUD 实现,基于 H2 内存数据库,适合学习和测试。

posted on 2025-02-22 21:57  joken1310  阅读(1327)  评论(0)    收藏  举报