SpringBoot中Entity、DTO、VO的通俗理解與實戰(zhàn)案例
SpringBoot中Entity、DTO、VO的通俗理解與實戰(zhàn)
剛接觸SpringBoot開發(fā)時,你是不是也有過這樣的困惑:明明數(shù)據(jù)庫表對應一個實體類就夠了,為什么還要搞出DTO、VO這些"花里胡哨"的東西?直接把數(shù)據(jù)庫實體類傳到前端不行嗎?
答案是:不行。就像我們寄快遞時,不會把家里的保險箱直接寄出去,而是會把里面的東西拿出來裝在快遞盒里(選需要的東西、去掉敏感信息)。Entity、DTO、VO就是這套"數(shù)據(jù)包裝"的不同容器,各自有明確的使用場景。今天咱們用最直白的案例,把這些概念講清楚。
一、Entity:和數(shù)據(jù)庫"一對一"的"原始數(shù)據(jù)袋"
定義:Entity(實體類)是數(shù)據(jù)庫表的"鏡像",字段和數(shù)據(jù)庫表一一對應,它的使命就是和數(shù)據(jù)庫打交道——存數(shù)據(jù)、取數(shù)據(jù)。
核心作用:作為持久層(Repository層)操作的載體,負責數(shù)據(jù)在Java對象和數(shù)據(jù)庫表之間的映射。
實戰(zhàn)案例:用戶表對應的Entity
假設數(shù)據(jù)庫有張user表,結(jié)構(gòu)如下:
| 字段名 | 類型 | 說明 |
|---|---|---|
| id | bigint | 主鍵 |
| username | varchar(50) | 用戶名 |
| password | varchar(100) | 加密密碼 |
| varchar(100) | 郵箱 | |
| create_time | datetime | 創(chuàng)建時間 |
| 對應的Entity類: |
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
// 與數(shù)據(jù)庫表user映射
@Entity
@Table(name = "user")
@Data // Lombok注解,自動生成getter、setter等
public class UserEntity {
// 主鍵
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 用戶名,對應表中username字段
private String username;
// 密碼(加密存儲),對應表中password字段
private String password;
// 郵箱,對應表中email字段
private String email;
// 創(chuàng)建時間,對應表中create_time字段
@Column(name = "create_time")
private LocalDateTime createTime;
}注意:Entity只應該在DAO層(數(shù)據(jù)訪問層)和Service層內(nèi)部使用,絕對不能直接傳到前端!因為它包含敏感信息(如password)和前端可能不需要的字段(如createTime)。
二、DTO:服務間數(shù)據(jù)傳輸?shù)?quot;快遞盒"
定義:DTO(Data Transfer Object,數(shù)據(jù)傳輸對象)用于不同服務之間、或服務內(nèi)部不同層之間傳遞數(shù)據(jù)。它就像快遞盒,只裝對方需要的數(shù)據(jù),不多不少。
核心作用:1. 減少數(shù)據(jù)傳輸量(只傳必要字段);2. 隔離不同服務的實體結(jié)構(gòu)(避免一個服務改實體影響另一個服務)。
實戰(zhàn)案例:用戶注冊的DTO
用戶注冊時,前端需要傳用戶名、密碼、郵箱,但不需要傳id(數(shù)據(jù)庫自增)和createTime(后端生成)。這時候就需要一個UserRegisterDTO:
import lombok.Data;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Email;
@Data
public class UserRegisterDTO {
// 用戶名不能為空
@NotBlank(message = "用戶名不能為空")
private String username;
// 密碼不能為空
@NotBlank(message = "密碼不能為空")
private String password;
// 郵箱格式要正確
@NotBlank(message = "郵箱不能為空")
@Email(message = "郵箱格式不正確")
private String email;
}Service層接收DTO并轉(zhuǎn)換為Entity:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void register(UserRegisterDTO registerDTO) {
// 1. DTO轉(zhuǎn)換為Entity
UserEntity userEntity = new UserEntity();
userEntity.setUsername(registerDTO.getUsername());
// 密碼加密(實際開發(fā)中一定要加密?。?
userEntity.setPassword(encryptPassword(registerDTO.getPassword()));
userEntity.setEmail(registerDTO.getEmail());
userEntity.setCreateTime(LocalDateTime.now());
// 2. 保存到數(shù)據(jù)庫
userRepository.save(userEntity);
}
// 密碼加密方法(示例)
private String encryptPassword(String rawPassword) {
return new BCryptPasswordEncoder().encode(rawPassword);
}
}三、VO:給前端展示的"最終商品"
定義:VO(View Object,視圖對象)是專門給前端頁面展示用的數(shù)據(jù)對象。它就像商店里的商品展示,只展示用戶想看到的信息,隱藏內(nèi)部細節(jié)。
核心作用:定制前端需要的展示數(shù)據(jù),比如字段別名、組合字段等。
實戰(zhàn)案例:用戶詳情的VO
前端展示用戶詳情時,需要id、用戶名、郵箱,但不需要password和createTime。這時候用UserVO:
import lombok.Data;
@Data
public class UserVO {
private Long id;
private String username;
private String email;
// 可以增加前端需要的組合字段,比如"用戶標簽"
private String userTag;
}Service層查詢Entity并轉(zhuǎn)換為VO:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public UserVO getUserDetail(Long userId) {
// 1. 從數(shù)據(jù)庫查詢Entity
UserEntity userEntity = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("用戶不存在"));
// 2. Entity轉(zhuǎn)換為VO
UserVO userVO = new UserVO();
userVO.setId(userEntity.getId());
userVO.setUsername(userEntity.getUsername());
userVO.setEmail(userEntity.getEmail());
// 定制前端需要的組合字段
userVO.setUserTag("普通用戶");
return userVO;
}
}Controller層返回VO給前端:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{userId}")
public UserVO getUserDetail(@PathVariable Long userId) {
return userService.getUserDetail(userId);
}
}四、三者轉(zhuǎn)換的"小技巧"
手動轉(zhuǎn)換(setter/getter)雖然直觀,但字段多了很麻煩。實際開發(fā)中推薦用工具類:
- ModelMapper:自動映射同名字段,支持自定義映射規(guī)則。
- MapStruct:編譯期生成映射代碼,性能更好,需要寫接口。
ModelMapper示例:
// 1. 引入依賴
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.2.0</version>
</dependency>
// 2. 配置Bean
@Configuration
public class ModelMapperConfig {
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
// 3. 服務中使用
@Service
public class UserService {
@Autowired
private ModelMapper modelMapper;
public UserVO getUserDetail(Long userId) {
UserEntity userEntity = userRepository.findById(userId).orElseThrow(...);
// 自動轉(zhuǎn)換Entity到VO
return modelMapper.map(userEntity, UserVO.class);
}
}五、總結(jié):一句話分清三者
| 對象類型 | 使用場景 | 核心目的 |
|---|---|---|
| Entity | DAO層 ↔ 數(shù)據(jù)庫 | 和數(shù)據(jù)庫表一一對應,負責數(shù)據(jù)持久化 |
| DTO | 服務間/層間數(shù)據(jù)傳輸 | 減少傳輸量,隔離服務依賴 |
| VO | Service層 ↔ 前端 | 定制前端展示數(shù)據(jù),隱藏敏感信息 |
| 記?。?strong>邊界清晰是代碼整潔的關(guān)鍵。用對Entity、DTO、VO,能讓你的SpringBoot項目結(jié)構(gòu)更清晰,維護性大大提升。 |
到此這篇關(guān)于SpringBoot中Entity、DTO、VO的通俗理解與實戰(zhàn)案例的文章就介紹到這了,更多相關(guān)SpringBoot Entity、DTO、VO內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC使用@Valid注解實現(xiàn)數(shù)據(jù)驗證的代碼示例
在 Web 開發(fā)中,數(shù)據(jù)驗證是一個非常重要的環(huán)節(jié),它可以確保數(shù)據(jù)的合法性和正確性,保護系統(tǒng)不受到惡意攻擊或用戶誤操作的影響,在 SpringMVC 中,我們可以使用 @Valid 注解來實現(xiàn)數(shù)據(jù)驗證,所以本文就給大家介紹具體的使用方法,需要的朋友可以參考下2023-07-07
IntelliJ IDEA使用tomcat和jetty配置詳解
這篇文章主要介紹了IntelliJ IDEA使用tomcat和jetty配置詳解,以便進一步地開發(fā)和調(diào)試,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10
基于SpringBoot實現(xiàn)上傳2種方法工程代碼實例
這篇文章主要介紹了基于SpringBoot實現(xiàn)上傳工程代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-08-08
ElasticSearch啟動成功卻無法在瀏覽器訪問問題解決辦法
因工作的需要,要使用elasticsearch,安裝完了,啟動也成功了之后發(fā)現(xiàn)了問題,這篇文章主要給大家介紹了關(guān)于ElasticSearch啟動成功卻無法在瀏覽器訪問問題的解決辦法,需要的朋友可以參考下2024-10-10
Springcloud GateWay網(wǎng)關(guān)配置過程圖解
這篇文章主要介紹了Springcloud GateWay網(wǎng)關(guān)配置過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-12-12
Java中的HashSet詳解和使用示例_動力節(jié)點Java學院整理
HashSet 是一個沒有重復元素的集合。接下來通過實例代碼給大家介紹java中的hashset相關(guān)知識,感興趣的朋友一起看看吧2017-05-05
Springcloud中的@RefreshScope的實現(xiàn)
@RefreshScope注解是Spring Cloud中的一個注解,它用來實現(xiàn)Bean中屬性的動態(tài)刷新,本文就來介紹一下@RefreshScope注解的使用,感興趣的可以了解一下2024-06-06

