DTO、VO、POJO與實體類使用方案(結合Mapper.xml)

結合MyBatis的Mapper.xml文件,展示完整的層級數據流轉和數據庫操作。

1. 實體類優化(Entity)

// User.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_user")
public class User {@TableId(type = IdType.AUTO)private Long userId;@NotBlankprivate String username;@NotBlankprivate String password;private String email;private String phone;private Date createTime;// 非數據庫字段,用于關聯查詢@TableField(exist = false)private List<Role> roles;
}// Role.java
@Data
@TableName("sys_role")
public class Role {@TableId(type = IdType.AUTO)private Long roleId;private String roleName;private String roleDesc;
}

2. Mapper接口與XML配置

UserMapper.java

@Mapper
public interface UserMapper {// 插入用戶并返回主鍵int insertUser(User user);// 根據ID查詢用戶(包含角色信息)User selectUserWithRoles(@Param("userId") Long userId);// 分頁查詢用戶List<User> selectUserList(UserQueryDTO queryDTO);// 批量插入用戶角色關系int batchInsertUserRoles(@Param("list") List<UserRole> userRoles);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.mapper.UserMapper"><!-- 基本結果映射 --><resultMap id="BaseUserMap" type="com.example.entity.User"><id column="user_id" property="userId"/><result column="username" property="username"/><result column="password" property="password"/><result column="email" property="email"/><result column="phone" property="phone"/><result column="create_time" property="createTime"/></resultMap><!-- 包含角色信息的用戶映射 --><resultMap id="UserWithRolesMap" type="com.example.entity.User" extends="BaseUserMap"><collection property="roles" ofType="com.example.entity.Role"><id column="role_id" property="roleId"/><result column="role_name" property="roleName"/><result column="role_desc" property="roleDesc"/></collection></resultMap><!-- 插入用戶 --><insert id="insertUser" useGeneratedKeys="true" keyProperty="userId">INSERT INTO sys_user (username, password, email, phone)VALUES (#{username}, #{password}, #{email}, #{phone})</insert><!-- 查詢用戶及其角色 --><select id="selectUserWithRoles" resultMap="UserWithRolesMap">SELECT u.*, r.role_id, r.role_name, r.role_descFROM sys_user uLEFT JOIN sys_user_role ur ON u.user_id = ur.user_idLEFT JOIN sys_role r ON ur.role_id = r.role_idWHERE u.user_id = #{userId}</select><!-- 動態查詢用戶列表 --><select id="selectUserList" resultMap="BaseUserMap">SELECT * FROM sys_user<where><if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if><if test="phone != null and phone != ''">AND phone = #{phone}</if><if test="createTimeStart != null">AND create_time >= #{createTimeStart}</if><if test="createTimeEnd != null">AND create_time &lt;= #{createTimeEnd}</if></where>ORDER BY create_time DESC</select><!-- 批量插入用戶角色關系 --><insert id="batchInsertUserRoles">INSERT INTO sys_user_role (user_id, role_id)VALUES<foreach collection="list" item="item" separator=",">(#{item.userId}, #{item.roleId})</foreach></insert>
</mapper>

3. 服務層優化實現

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {private final UserMapper userMapper;private final RoleMapper roleMapper;private final PasswordEncoder passwordEncoder;@Override@Transactionalpublic UserVO createUser(UserDTO userDTO) {// DTO轉EntityUser user = new User();BeanUtils.copyProperties(userDTO, user);// 密碼加密user.setPassword(passwordEncoder.encode(userDTO.getPassword()));// 保存用戶userMapper.insertUser(user);// 保存用戶角色關系if (!CollectionUtils.isEmpty(userDTO.getRoleIds())) {List<UserRole> userRoles = userDTO.getRoleIds().stream().map(roleId -> new UserRole(user.getUserId(), roleId)).collect(Collectors.toList());userMapper.batchInsertUserRoles(userRoles);}// 返回完整的用戶信息return getUserVO(user.getUserId());}@Overridepublic PageVO<UserVO> getUsers(UserQueryDTO queryDTO) {// 設置分頁參數PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize());// 查詢用戶列表List<User> users = userMapper.selectUserList(queryDTO);PageInfo<User> pageInfo = new PageInfo<>(users);// 轉換為VO列表List<UserVO> userVOs = users.stream().map(user -> UserVO.fromEntity(user, getRolesByUserId(user.getUserId()))).collect(Collectors.toList());// 構建分頁VOreturn new PageVO<>(pageInfo.getTotal(),pageInfo.getPageNum(),pageInfo.getPageSize(),userVOs);}@Overridepublic UserVO getUserVO(Long userId) {User user = userMapper.selectUserWithRoles(userId);return UserVO.fromEntity(user, user.getRoles());}private List<Role> getRolesByUserId(Long userId) {return roleMapper.selectByUserId(userId);}
}

4. DTO/VO優化設計

UserDTO.java

@Data
public class UserDTO {@NotBlank(message = "用戶名不能為空")@Size(min = 4, max = 20)private String username;@NotBlank(message = "密碼不能為空")@Size(min = 6, max = 20)@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d).*$", message = "密碼必須包含字母和數字")private String password;@Emailprivate String email;@Pattern(regexp = "^1[3-9]\\d{9}$")private String phone;@NotEmpty(message = "至少分配一個角色")private List<Long> roleIds;// 自定義轉換方法public User toEntity() {User user = new User();BeanUtils.copyProperties(this, user);return user;}
}

UserVO.java

@Data
@Accessors(chain = true)
public class UserVO {private Long userId;private String username;private String email;private String phone;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;private List<RoleVO> roles;// 靜態工廠方法public static UserVO fromEntity(User user, List<Role> roles) {return new UserVO().setUserId(user.getUserId()).setUsername(user.getUsername()).setEmail(user.getEmail()).setPhone(user.getPhone()).setCreateTime(user.getCreateTime()).setRoles(roles.stream().map(RoleVO::fromEntity).collect(Collectors.toList()));}
}

PageVO.java (通用分頁VO)

@Data
@AllArgsConstructor
public class PageVO<T> {private Long total;private Integer pageNum;private Integer pageSize;private List<T> list;// 計算總頁數public Integer getPages() {if (pageSize == 0) return 0;return (int) Math.ceil((double) total / pageSize);}
}

5. 控制器層優化

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {private final UserService userService;@PostMappingpublic ResponseEntity<Result<UserVO>> createUser(@Valid @RequestBody UserDTO userDTO) {UserVO userVO = userService.createUser(userDTO);return ResponseEntity.ok(Result.success(userVO));}@GetMappingpublic ResponseEntity<Result<PageVO<UserVO>>> getUsers(@Valid UserQueryDTO queryDTO) {PageVO<UserVO> page = userService.getUsers(queryDTO);return ResponseEntity.ok(Result.success(page));}@GetMapping("/{userId}")public ResponseEntity<Result<UserVO>> getUser(@PathVariable Long userId) {UserVO userVO = userService.getUserVO(userId);return ResponseEntity.ok(Result.success(userVO));}
}// 通用返回結果
@Data
@AllArgsConstructor
class Result<T> {private int code;private String message;private T data;public static <T> Result<T> success(T data) {return new Result<>(200, "success", data);}
}

6. 優化后的數據流轉流程

  1. 前端請求Controller(接收DTO并校驗)
  2. ControllerService(傳遞DTO)
  3. Service
    • 將DTO轉換為Entity
    • 調用Mapper進行數據庫操作
    • 將查詢結果Entity轉換為VO
  4. ServiceController(返回VO)
  5. Controller前端(返回VO數據)

7. 關鍵優化點

  1. Mapper.xml優化

    • 使用resultMap實現復雜結果映射
    • 動態SQL處理各種查詢條件
    • 批量操作提高性能
  2. 對象轉換優化

    • 在DTO/VO中定義轉換方法
    • 使用鏈式調用簡化代碼
    • 靜態工廠方法提高可讀性
  3. 分頁處理

    • 使用PageHelper實現物理分頁
    • 統一分頁返回結構
  4. 驗證增強

    • 在DTO中使用更精細的驗證注解
    • 密碼復雜度驗證
  5. 性能優化

    • 關聯查詢減少數據庫訪問次數
    • 批量插入提高效率

這種結構清晰地區分了各層職責,使代碼更易維護和擴展,同時保證了良好的性能。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89259.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89259.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89259.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開源|VDBBench 1.0正式官宣,完全復刻業務場景,支持用戶自定義數據集

宣布個好消息&#xff0c;大家期待已久的VDBBench 1.0更新啦。 嘗鮮鏈接&#xff1a; https://github.com/zilliztech/VectorDBBench/releases/tag/v1.0.0 對于這個功能的更新&#xff0c;我們準備了很久&#xff0c;也思考了很多。 因為對我們來說&#xff0c;VDBBench 從來不…

7,FreeRTOS列表與列表項的插入刪除

一、實驗目標 創建三個動態任務&#xff0c;棧空間大小均為128字。startTask、Task1、Task2。startTask僅運行一次&#xff0c;負責task1、task2任務的創建&#xff0c;startTask任務的刪除。Task1負責初始化列表、列表項123&#xff0c;并進行列表項的插入實驗與刪除實驗。Tas…

兩款支持3D地圖的WebGIS框架對比

前言 在當前的WebGIS技術發展中&#xff0c;3D地形圖的可視化已經成為一個非常重要的功能&#xff0c;尤其是在城市規劃、環境監測和虛擬旅游等領域中的應用。對于開發者而言&#xff0c;選擇一個強大且適合的WebGIS框架是實現這些功能的關鍵。目前市場上較為流行的支持3D地形…

Github 2025-06-26 Go開源項目日報Top10

根據Github Trendings的統計,今日(2025-06-26統計)共有10個項目上榜。根據開發語言中項目的數量,匯總情況如下: 開發語言項目數量Go項目10PureBasic項目1使用Gitleaks保護和發現機密信息 創建周期:2203 天開發語言:Go協議類型:MIT LicenseStar數量:14645 個Fork數量:13…

C++實現魷魚、羊了個羊、掃雷、原神模擬

C++ 魷魚游戲模擬實現 魷魚游戲中的經典場景可以通過C++模擬實現,例如“紅綠燈”游戲。以下是一個簡化版本的核心代碼框架: #include <iostream> #include <thread> #include <chrono> #include <cstdlib> #include <ctime> #include <ve…

從用戶到權限:解密 AWS IAM Identity Center 的授權之道

大家好&#xff0c;今天我們來解決一個非常具體的實戰問題&#xff1a;如何讓 IAM Identity Center 中創建的用戶真正獲得 AWS 賬戶的操作權限&#xff0c;從而取代老舊的 IAM 用戶管理模式&#xff1f; 如果我們盯著用戶詳情頁&#xff0c;想找一個“附加角色”的按鈕&#x…

在 Spring Boot 中使用 MyBatis-Plus 的詳細教程

前言 在現代的 Java Web 開發中&#xff0c;Spring Boot 和 MyBatis 已經成為主流框架組合。為了提升開發效率和簡化數據庫操作&#xff0c;MyBatis-Plus&#xff08;簡稱 MP&#xff09;應運而生。它是一個 MyBatis 的增強工具&#xff0c;在 MyBatis 的基礎上只做增強不做改…

AI生成內容泛濫時代:從“袋鼠登機“視頻看AI鑒偽與游戲智能的未來

近年來&#xff0c;AI生成內容的質量突飛猛進&#xff0c;從文本到圖像再到視頻&#xff0c;幾乎達到了以假亂真的程度。近期一段"人類在飛機上吵架看呆袋鼠"的視頻在社交網絡瘋傳&#xff0c;獲得數千萬次觀看后&#xff0c;才被證實是AI生成內容&#xff0c;這一事…

為什么在linux中不能直接使用pip進行安裝

您好&#xff0c;這是一個非常深刻且關鍵的問題&#xff0c;觸及了 Linux 系統管理與 Python 開發實踐的核心原則。理解了這一點&#xff0c;您就真正開始像一位經驗豐富的開發者那樣思考了。 簡單來說&#xff0c;答案是&#xff1a;為了保護操作系統自身的穩定和完整性。 讓…

IDEA相關配置記錄

IDEA相關配置記錄 參考鏈接&#xff1a; 參考鏈接&#xff1a; 1、安裝jdk D:\Program Files\Java\jdk-21 https://blog.csdn.net/2302_81410974/article/details/142031416 2、安裝maven D:\Java\workspace-maven\apache-maven-3.9.10 . ├── LICENSE ├── NOTICE ├──…

FastGPT私有化部署完整指南

&#x1f680; FastGPT 私有化部署完整指南 &#x1f4cb; 環境要求 硬件要求 最低配置:CPU: 4核內存: 8GB存儲: 50GB網絡: 穩定互聯網連接推薦配置:CPU: 8核內存: 16GB存儲: 100GB SSD網絡: 10Mbps帶寬軟件環境 必需軟件:- Docker: > 20.10.0- Docker Compose: > 2.…

系統架構設計師論文分享-基于架構的軟件設計方法及應用

我的軟考歷程 摘要 2023年2月&#xff0c;我所在的公司做了開發紗線MES系統的決定&#xff0c;該系統為國內紗線工廠提供SAAS服務&#xff0c;旨在提高紗線工廠的智能化和數字化水平。我在該項目中被任命為系統架構設計師&#xff0c;全面掌管該項目的架構設計工作。本文將結…

團結引擎發布純鴻蒙應用

大家好&#xff0c;我是阿趙。 ??這里嘗試一下用團結引擎發布純鴻蒙系統的應用。 一、 安裝鴻蒙系統發布需要的組件 在團結引擎的Hub里面找到Add modules: 然后找到OpenHarmony的支持選項&#xff0c;由于我已經安裝過了&#xff0c;所以會顯示Installed&#xff0c;如果沒…

C++基礎(FreeRDP編譯)

安裝 先安裝openssl 保姆級OpenSSL下載及安裝教程,OpenSSL下載及安裝教程-CSDN博客 vcpkg integrate install 安裝 vcpkg install zlib vcpkg install ffmpeg:x64-windows 編譯指令 PS D:\freerdp\FreeRDP\build> cmake .. -G "Visual Studio 17 2022" -A x…

用celery作為信息中間件

要在 Django 的 settings.py 中設置 Redis 作為 Celery 的 broker 和(可選)backend,你需要添加如下配置: 安裝依賴(如未安裝): pip install celery redis在 settings.py 中添加 Celery 配置(推薦放在文件底部): # Celery 配置 CELERY_BROKER_URL = redis://127.0.0.1…

Postman介紹及使用

Postman 是一個強大的 API 開發、測試和文檔化工具&#xff0c;廣泛用于開發者、測試人員和 API 設計者。以下是 Postman 的核心使用指南&#xff0c;涵蓋基礎操作到進階功能&#xff1a; 一、基礎使用 安裝與界面 下載&#xff1a;官網下載&#xff08;支持 Windows/macOS/Lin…

Android14音頻子系統-ASoC-ALSA之DAPM電源管理子系統

文章目錄 概述1&#xff09;codec對象-WM89602&#xff09;ALSA下的kcontrol的構造與使用3&#xff09;ASOC-ALSA下的kcontrol構造與使用1、通用寄存器對象 - kcontrol2、DAPM下的寄存器對象-widget3、如何構造widget&#xff1f;4、抽象對象widget、route與path1&#xff09;r…

如何修改anaconda 創建新虛擬環境的路徑(默認是C:\.conda\envs)

參考文章&#xff1a; 如何修改anaconda 創建新虛擬環境的路徑(默認是C&#xff1a;\.conda\envs)_anaconda創建環境怎么改路徑-CSDN博客

前綴和計算

前綴和 輸入一個長度為n的整數序列。接下來再輸入m個詢問&#xff0c;每個詢問輸入一對l, r。對于每個詢問&#xff0c;輸出原序列中從第l個數到第r個數的和。 所用方法和基本原理 前綴和數組的構建&#xff1a; 首先定義了一個方法getPrefixSum來構建前綴和數組。前綴和數組…

BP神經網絡支持向量機實現風機故障診斷

BP神經網絡&#xff0c;支持向量機等用于風機故障診斷 BP神經網絡&#xff0c;支持向量機等用于風機故障診斷/成功算法/bp20111202_FDD.m , 1580 BP神經網絡&#xff0c;支持向量機等用于風機故障診斷/成功算法/BP_FDD.m , 6044 BP神經網絡&#xff0c;支持向量機等用于風機故…