Spring的业务层,持久层,控制层的关系

在 Spring 框架中,控制层(Controller)业务层(Service) 和 持久层(Repository/Mapper) 是分层架构的核心组成部分,职责分离明确,通过依赖注入(DI)协作。

1. 各层职责

(1) 控制层(Controller)

  • 作用:处理 HTTP 请求和响应,是前后端交互的入口。

  • 职责

    • 接收请求参数(如 @RequestParam@RequestBody)。

    • 调用 业务层 处理逻辑。

    • 返回 JSON 数据或视图(如 @ResponseBody)。

  • 核心注解

    • @Controller(返回视图)或 @RestController(纯 API,返回 JSON)。

(2) 业务层(Service)

  • 作用:处理 核心业务逻辑(如订单计算、权限校验)。

  • 职责

    • 组合多个持久层操作(如事务管理)。

    • 处理业务规则(如数据校验、流程控制)。

    • 调用 持久层 操作数据库。

  • 核心注解

    • @Service(标识业务组件)。

    • @Transactional(管理事务)。

(3) 持久层(Repository/Mapper)

  • 作用:直接与 数据库交互,执行 CRUD 操作。

  • 职责

    • 定义数据库操作方法(如 SQL 或 ORM 映射)。

    • 屏蔽数据库细节(如 MySQL 或 MongoDB 差异)。

  • 核心注解

    • JPA:@Repository(接口继承 JpaRepository)。

    • MyBatis:@Mapper(接口 + XML/SQL 映射)。

2. 各层协作关系

(1) 调用流程

HTTP请求 → Controller → Service → Repository → 数据库↑返回响应        ↑业务逻辑         ↑SQL执行
  1. Controller 接收请求参数,校验格式。

  2. Service 处理业务逻辑(如订单总价计算),调用 Repository 读写数据。

  3. Repository 执行 SQL 或通过 ORM 操作数据库,返回结果给 Service。

  4. Service 处理完成后,返回数据给 Controller。

  5. Controller 封装响应(如 JSON),返回给前端。

(2) 依赖关系

  • 单向依赖

    Controller → Service → Repository
    • 上层依赖下层,下层不感知上层(如 Repository 不依赖 Service)。

    • 通过 @Autowired 实现依赖注入。

3. 分层优势

优势说明
职责分离各层专注单一职责(如 Controller 处理请求,Service 处理业务)。
代码复用多个 Controller 可共用同一个 Service(如订单和支付模块共用用户服务)。
易于维护修改数据库逻辑只需调整 Repository,不影响 Service 和 Controller。
事务管理事务注解(@Transactional)通常放在 Service 层,确保业务操作原子性。
测试友好可单独测试 Service 逻辑,Mock 数据库操作(如使用 Mockito)。

4. 实际开发中的常见问题

(1) 能不能跳过 Service,直接 Controller 调用 Repository?

  • 不推荐!会导致:

    • 业务逻辑散落在 Controller 中,难以复用。

    • 事务管理困难(如多个 Repository 操作无法统一回滚)。

(2) Service 层为什么需要接口?

  • 接口的作用

    • 实现类可替换(如切换缓存策略)。

    • 便于 AOP 代理(如事务管理、日志切面)。

      public interface UserService {  // 接口User getUserById(Long id);
      }@Service
      public class UserServiceImpl implements UserService {  // 实现类// 具体逻辑
      }

    (3) 实体类(Entity)放在哪一层?

  • 通常独立为领域模型层

    com.example.project
    ├── controller
    ├── service
    ├── repository
    └── entity  // 实体类(User、Order)
    • 所有层共享实体类,但 避免将实体直接暴露给前端(建议用 DTO 转换)。

5. 总结

  • Controller:处理 HTTP 交互,参数校验,调用 Service。

  • Service:核心业务逻辑,事务管理,调用 Repository。

  • Repository:数据库操作,屏蔽 SQL 细节。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/81829.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css实现不确定内容的高度过渡

实现效果&#xff1a;鼠标悬浮按钮&#xff0c;高度过渡出现如图所示文本框 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-widt…

计算机视觉与深度学习 | matlab实现ARIMA-WOA-CNN-LSTM时间序列预测(完整源码和数据)

以下是一个基于MATLAB的ARIMA-WOA-CNN-LSTM时间序列预测框架。由于完整代码较长,此处提供核心模块和实现思路,完整源码和数据可通过文末方式获取。 1. 数据准备(示例数据) 使用MATLAB内置的航空乘客数据集: % 加载数据 data = readtable(airline-passengers.csv); data …

在 Excel 中使用东方仙盟软件————仙盟创梦IDE

安装插件 用仙盟创梦编写插件代码 源码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ExcelDna.Integration;namespace 东方仙盟.仙盟创梦IDE_招标系统 {public static class 仙盟创梦_招标专…

Sql刷题日志(day9)

一、笔试 1、limit offset&#xff1a;分页查询 SELECT column1, column2, ... FROM table_name LIMIT number_of_rows OFFSET start_row; --跳过前 start_row 行&#xff0c;返回接下来的 number_of_rows 行。 2、lag、lead&#xff1a;查询前后行数据 --lag函数用于访问当…

C++面试3——const关键字的核心概念、典型场景和易错陷阱

const关键字的核心概念、典型场景和易错陷阱 一、const本质&#xff1a;类型系统的守护者 1. 与#define的本质差异 维度#defineconst编译阶段预处理替换编译器类型检查作用域无作用域&#xff08;全局污染&#xff09;遵循块作用域调试可见性符号消失保留符号信息类型安全无类…

16-看门狗和RTC

一、独立看门狗 1、独立看门狗概述 在由单片机构成的微型计算机系统中&#xff0c;由于单片机的工作常常会受到来自外界电磁场的干扰&#xff0c;造成程序的跑飞&#xff08;不按照正常程序进行运行&#xff0c;如程序重启&#xff0c;但是如果我们填加看门狗的技术&#xff0…

w~自动驾驶~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/13269720 #FastOcc 推理更快、部署友好Occ算法来啦&#xff01; 在自动驾驶系统当中&#xff0c;感知任务是整个自驾系统中至关重要的组成部分。感知任务的主要目标是使自动驾驶车辆能够理解和感知周围的环境元素&…

怎么打包发布到npm?——从零到一的详细指南

怎么打包发布到npm&#xff1f;——从零到一的详细指南 目录 怎么打包发布到npm&#xff1f;——从零到一的详细指南一、准备工作1. 注册 npm 账号2. 安装 Node.js 和 npm 二、初始化项目三、编写你的代码四、配置 package.json五、打包你的项目六、登录 npm七、发布到 npm八、…

【C++ - 仿mudou库one thread one loop式高并发服务器实现】

文章目录 项目介绍项目模块和服务器主要设计模式项目主要流程前置知识1.bind函数2.定时器任务TimerTask和时间轮思想TimerWheel3.正则表达式4.通用型容器Any类 服务器设计模式1&#xff09;单Reactor单线程模式2&#xff09;单Reactor多线程模式3&#xff09;多Reactor多线程模…

RISC-V 开发板 MUSE Pi Pro USB 测试(3.0 U盘,2.0 UVC摄像头)

视频讲解&#xff1a; RISC-V 开发板 MUSE Pi Pro USB 测试&#xff08;3.0 U盘&#xff0c;2.0 UVC摄像头&#xff09; 总共开发板有4个USB的A口&#xff0c;1个USB的TypeC口&#xff0c;我们插上两个USB3.0的U盘和一个USB2.0的UVC摄像头来进行测试 lsusb -tv 可以看到有3个US…

docker学习与使用(概念、镜像、容器、数据卷、dockerfile等)

文章目录 前言引入docker 简介docker的应用场景docker的虚拟化技术VS虚拟机docker的优点docker架构Docker仓库Docker镜像linux操作系统的大致组成部分 Docker容器 docker安装与启动校验版本移除旧的版本安装依赖工具设置软件源安装docker验证 配置镜像加速器docker服务相关命令…

记录一次服务器卡顿

一、服务器卡顿现象 服务用了一段时间后&#xff0c;突然很卡&#xff0c;发现在服务器上新建excel也很卡&#xff0c;发现服务器中病毒了&#xff0c;然后重新安装了操作系统。重新安装服务环境时&#xff0c;发现同时安装pdf、tomcat时都很慢&#xff0c;只能一个安装好了&am…

基于 Reactor 的 Java 高性能异步编程:响应式流与背压详解

本文将围绕 Reactor 框架&#xff0c;深入剖析响应式流的核心机制&#xff0c;重点讲解背压&#xff08;Backpressure&#xff09;的实现原理与实际应用。通过理论结合实践&#xff0c;希望帮助你真正掌握 Java 世界的响应式异步编程。 一、响应式编程与 Reactor 简介 1.1 什么…

知识蒸馏实战:用PyTorch和预训练模型提升小模型性能

在深度学习的浪潮中&#xff0c;我们常常追求更大、更深、更复杂的模型以达到最先进的性能。然而&#xff0c;这些“庞然大物”般的模型往往伴随着高昂的计算成本和缓慢的推理速度&#xff0c;使得它们难以部署在资源受限的环境中&#xff0c;如移动设备或边缘计算平台。知识蒸…

python:mysql全局大览(保姆级教程)

本文目录&#xff1a; 一、关于数据库**二、sql语言分类**三、数据库增删改查操作**四、库中表增删改查操作**五、表中记录插入**六、表约束**七、单表查询**八、多表查询**&#xff08;一&#xff09;外键约束**&#xff08;二&#xff09;连结查询**1.交叉连接&#xff08;笛…

Android framework 问题记录

一、休眠唤醒&#xff0c;很快熄屏 1.1 问题描述 机器休眠唤醒后&#xff0c;没有按照约定的熄屏timeout 进行熄屏&#xff0c;很快就熄屏&#xff08;约2s~3s左右&#xff09; 1.2 原因分析&#xff1a; 抓取相关log&#xff0c;打印休眠背光 相关调用栈 //具体打印调用栈…

怎么利用JS根据坐标判断构成单个多边形是否合法

怎么利用JS根据坐标判断构成单个多边形是否合法 引言 在GIS(地理信息系统)、游戏开发、计算机图形学等领域,判断一组坐标点能否构成合法的简单多边形(Simple Polygon)是一个常见需求。合法多边形需要满足几何学上的基本规则,本文将详细介绍如何使用JavaScript实现这一判…

sqlite的拼接字段的方法(sqlite没有convert函数)

我在sqlserver 操作方式&#xff1a; /// <summary>///获取当前门店工资列表/// </summary>/// <param name"wheres">其他条件</param>/// <param name"ThisMendian">当前门店</param>/// <param name"IsNotU…

构建高效移动端网页调试流程:以 WebDebugX 为核心的工具、技巧与实战经验

现代前端开发早已不仅仅局限于桌面浏览器。随着 Hybrid 应用、小程序、移动 Web 的广泛应用&#xff0c;开发者日常面临的一个关键挑战是&#xff1a;如何在移动设备上快速定位并解决问题&#xff1f; 这不再是“打开 DevTools 查查 Console”的问题&#xff0c;而是一个关于设…

新兴技术与安全挑战

7.1 云原生安全(K8s安全、Serverless防护) 核心风险与攻击面 Kubernetes配置错误: 风险:默认开放Dashboard未授权访问(如kubectl proxy未鉴权)。防御:启用RBAC,限制ServiceAccount权限。Serverless函数注入: 漏洞代码(AWS Lambda):def lambda_handler(event, cont…