0

0

Spring MVC与Hibernate删除操作:ID或模型传递的最佳实践

霞舞

霞舞

发布时间:2025-10-05 11:38:30

|

778人浏览过

|

来源于php中文网

原创

Spring MVC与Hibernate删除操作:ID或模型传递的最佳实践

在Spring MVC与Hibernate应用中执行记录删除操作时,通常的最佳实践是直接通过ID进行删除,而非先检索完整模型再删除。这种方法更高效,因为它避免了不必要的数据库查询,并且在分层架构中,当仅需唯一标识符执行特定操作时,直接传递ID是完全合理的,并非必须始终传递完整的领域模型。

理解分层架构中的数据流

典型的java web应用会采用分层架构,例如:

  • 视图层 (Views):用户界面,负责展示数据并接收用户输入。
  • 控制器层 (Controllers):处理来自视图层的请求,协调业务逻辑,并将结果返回给视图。
  • 服务层 (Services):封装业务逻辑,协调多个DAO操作,并处理事务。
  • 数据访问层 (DAO - Data Access Objects):负责与数据库进行交互,执行CRUD操作。
  • 数据库 (DB):存储和管理数据。

当需要删除一条记录时,前端通常会向控制器发送一个标识符(如ID)。此时,开发者面临一个选择:是将这个ID直接传递到服务层和DAO层进行删除,还是在控制器层先根据ID检索出完整的模型对象,再将模型对象传递下去进行删除。

方案一:通过ID直接删除(推荐实践)

这是在大多数删除场景下推荐的做法。

工作流程

  1. 视图层:用户点击删除按钮,将待删除记录的ID发送到控制器。
  2. 控制器层:接收到ID参数。
  3. 服务层:控制器将ID传递给服务层的方法(例如 userService.deleteUser(id))。服务层可能会执行一些业务逻辑检查(例如权限验证),然后将ID传递给DAO层。
  4. 数据访问层 (DAO):DAO接收到ID后,直接使用Hibernate或JPA的API执行删除操作,例如 session.delete(id) 或 entityManager.remove(entityManager.getReference(Entity.class, id))。

示例代码(概念性)

// Controller层
@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @DeleteMapping("/{id}")
    public ResponseEntity deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

// Service层
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Transactional
    public void deleteUser(Long id) {
        // 可选:在这里添加业务逻辑,例如权限检查
        userDao.delete(id);
    }
}

// DAO层
@Repository
public class UserDao {

    @PersistenceContext
    private EntityManager entityManager; // 或使用SessionFactory

    public void delete(Long id) {
        // 推荐使用getReference()或createQuery()来避免不必要的select
        // entityManager.remove(entityManager.getReference(User.class, id));
        // 更直接的方式是使用JPQL或HQL进行批量删除,或通过id查找后删除
        User user = entityManager.find(User.class, id); // 实际操作中,如果仅知ID,通常不需要先find
        if (user != null) {
            entityManager.remove(user);
        } else {
            // 处理记录不存在的情况
            throw new EntityNotFoundException("User with ID " + id + " not found.");
        }

        // 或者直接通过JPQL/HQL删除,效率更高,但不会触发级联删除(如果配置了)
        // Query query = entityManager.createQuery("DELETE FROM User u WHERE u.id = :id");
        // query.setParameter("id", id);
        // query.executeUpdate();
    }
}

优点

  • 效率高:只需要一次数据库查询(或直接删除操作),避免了不必要的 SELECT 查询。
  • 简洁明了:代码逻辑清晰,直接表达了“根据ID删除”的意图。
  • 资源消耗低:不需要将完整的实体对象加载到内存中。

方案二:先检索模型再删除

这种方法通常不推荐用于简单的删除操作。

工作流程

  1. 视图层:用户点击删除按钮,将待删除记录的ID发送到控制器。
  2. 控制器层:接收到ID参数。在这里,控制器会先调用服务层或DAO层根据ID检索出完整的模型对象。
  3. 服务层:控制器将检索到的模型对象传递给服务层的方法(例如 userService.deleteUser(userModel))。服务层可能会执行业务逻辑,然后将模型对象传递给DAO层。
  4. 数据访问层 (DAO):DAO接收到模型对象后,使用Hibernate或JPA的API执行删除操作,例如 session.delete(userModel) 或 entityManager.remove(userModel)。

缺点

  • 效率低下:需要两次数据库操作——一次 SELECT 查询来检索模型,另一次 DELETE 操作来删除模型。
  • 资源浪费:将不必要的完整实体对象加载到内存中。
  • 复杂性增加:增加了额外的代码和逻辑,而对于简单的删除操作而言是不必要的。

何时可能考虑?

只有在极少数情况下,如果删除操作需要基于实体对象的完整当前状态进行复杂的业务逻辑判断(例如,在删除前需要检查多个字段的值或执行复杂的审计操作),才可能考虑在服务层(而非控制器层)先加载实体。但即便如此,也应将加载操作放在服务层内部,以保持控制器层的轻量级。对于绝大多数删除场景,直接通过ID删除是更优选择。

澄清“通过模型而非参数传递”的原则

开发者有时会误解“我们应该通过模型而非参数传递数据”这一原则。这个原则更多地适用于数据创建、更新或需要传递复杂业务上下文的场景。在这种情况下,一个包含多个字段的DTO(数据传输对象)或领域模型可以更好地封装数据,避免方法签名过长或参数过多。

Voicenotes
Voicenotes

Voicenotes是一款简单直观的多功能AI语音笔记工具

下载

然而,对于基于唯一标识符的简单操作,如检索(findById(id))或删除(deleteById(id)),直接传递ID是完全合理且更高效的。ID本身就是一种简洁而明确的“参数”,足以完成特定任务,无需加载整个模型。

总结与最佳实践

在Spring MVC与Hibernate的删除操作中,最佳实践是:

  1. 直接通过ID删除:当仅需删除一条记录且无需其完整状态进行复杂业务判断时,从控制器到服务层再到DAO层,直接传递记录的唯一标识符(ID)进行删除。
  2. 服务层负责业务逻辑:任何删除前的业务校验(如权限、状态检查)都应在服务层完成。
  3. DAO层专注于持久化:DAO层接收ID后,直接执行高效的删除操作,避免不必要的 SELECT 查询。
  4. 事务管理:确保删除操作在事务中执行,以保证数据的一致性。

遵循这些原则,可以构建出高效、可维护且符合分层架构最佳实践的Spring MVC与Hibernate应用程序。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

115

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

31

2026.01.26

hibernate和mybatis有哪些区别
hibernate和mybatis有哪些区别

hibernate和mybatis的区别:1、实现方式;2、性能;3、对象管理的对比;4、缓存机制。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

143

2024.02.23

Hibernate框架介绍
Hibernate框架介绍

本专题整合了hibernate框架相关内容,阅读专题下面的文章了解更多详细内容。

84

2025.08.06

Java Hibernate框架
Java Hibernate框架

本专题聚焦 Java 主流 ORM 框架 Hibernate 的学习与应用,系统讲解对象关系映射、实体类与表映射、HQL 查询、事务管理、缓存机制与性能优化。通过电商平台、企业管理系统和博客项目等实战案例,帮助学员掌握 Hibernate 在持久层开发中的核心技能。

36

2025.09.02

Hibernate框架搭建
Hibernate框架搭建

本专题整合了Hibernate框架用法,阅读专题下面的文章了解更多详细内容。

67

2025.10.14

session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

315

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

751

2023.10.18

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 7.9万人学习

Java 教程
Java 教程

共578课时 | 53.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号