Entity 层数据库表的映射表多少类多少。Dao层与数据库交互用 SQL 查数据。Dao Data Access ObjectMapper 层MyBatis 的实现方式接口 XMLService 层业务逻辑层如银行取钱的业务处理。Controller层对外提供接口供前端调用。分层的意义好维护、好定位问题、方便做事务/权限/日志等统一处理。DTO/VO/BO分层DTOData Transfer Object数据传输对象给谁用前端 → 后端作用接收前端传过来的参数特点只存需要的字段不包含数据库无关内容例子用户登录只需要usernamepassword就建一个LoginDTO好处不会把一堆没用的字段塞进来代码更清晰安全避免前端传入恶意字段污染 EntityVOView Object展示对象给谁用后端 → 前端作用专门给前端页面展示用特点可以组合多个 Entity 的数据、加工后的数据例子用户列表 VO 可以包含username、nickname、roleName但绝不返回 passwordBOBusiness Object业务对象给谁用Service 层内部用作用封装复杂业务数据特点Controller 和前端看不见只在业务逻辑里流转为什么这分层在代码审计里极其关键千万不要把 Entity 直接返回给前端Entity 里有password、phone、id_card、create_time等敏感字段直接返回就是敏感信息泄露漏洞正确结构前端请求 → DTO → Controller → Service → BO → Mapper → Entity数据库 数据库返回 → Entity → Service → BO → VO → 前端总结Entity 只碰数据库DTO收前端VO给前端绝不直接返回 Entity全局异常处理作用统一捕获项目所有异常不让系统抛出冗长报错堆栈给前端统一返回格式更规范、更安全关键安全点如果不处理报错时前端会看到异常堆栈代码行数类名数据库信息就会出现异常信息泄露漏洞 → 高危用法RestControllerAdvice public class GlobalExceptionHandler { // 捕获所有异常 ExceptionHandler(Exception.class) public Result handleException(Exception e) { // 只返回友好提示不返回堆栈 return Result.fail(系统异常请稍后重试); } // 自定义业务异常 ExceptionHandler(BusinessException.class) public Result handleBusinessException(BusinessException e) { return Result.fail(e.getMessage()); } }效果前端永远只看到干净的 JSON不会泄露任何内部信息统一返回体封装所有接口返回格式一模一样标准结构Data public class ResultT { // 200成功 500失败 private int code; // 提示信息 private String msg; // 数据 // 这里使用泛型是让返回体可以装任意类型的数据保持类型安全 private T data; // 常用静态方法 public static T ResultT success(T data) { ... } public static T ResultT success() { ... } public static T ResultT fail(String msg) { ... } }接口使用GetMapping(/user/{id}) public ResultUserVO getUser(PathVariable Long id) { // 为什么不使用RequestParam而是使用PathVariable // 因为RequestParam这个是取后面的参数 // 比如 /user?id1001 → 取 1001 // 而PathVariable这个是路径里的值 // 比如 /user/1001 → 取 1001 UserVO user userService.getUserById(id); return Result.success(user); }前端收到{ code: 200, msg: 操作成功, data: { ... } }