0

0

Spring MVC与Hibernate删除记录的最佳实践:参数传递策略解析

心靈之曲

心靈之曲

发布时间:2025-10-05 10:17:02

|

822人浏览过

|

来源于php中文网

原创

Spring MVC与Hibernate删除记录的最佳实践:参数传递策略解析

在Spring MVC和Hibernate应用中删除记录时,最佳实践是直接通过ID进行删除,而不是先加载完整模型再删除。这种方法能有效减少数据库查询次数,提高系统性能,并简化业务逻辑,同时在服务层进行必要的权限和业务校验。

1. 理解多层架构中的删除操作

典型的java web应用通常采用多层架构,例如:视图层 (views) -> 控制器层 (controllers) -> 服务层 (services) -> 数据访问层 (dao) -> 数据库 (db)。当需要删除一条记录时,前端通常只传递该记录的唯一标识符(id)。核心问题在于,这个id应该如何向下传递,以及在哪个层级执行删除操作。

我们面临两种主要的策略:

  1. 直接通过ID删除: 控制器接收ID后,将其传递给服务层,服务层再委托给DAO层,DAO层直接根据ID执行删除操作。
  2. 先加载模型再删除: 控制器接收ID后,可能在控制器层或服务层先根据ID从数据库加载完整的实体模型,然后将这个模型传递给服务层和DAO层,DAO层再删除这个模型。

2. 策略分析与比较

2.1 策略一:直接通过ID删除

流程:View (ID) -> Controller (ID) -> Service (ID) -> DAO (ID) -> DB (DELETE by ID)

优点:

ZOER
ZOER

AI全栈应用开发平台

下载
  • 性能优化: 只需要执行一次数据库操作(DELETE语句)。这是最显著的优势,避免了不必要的SELECT查询。
  • 简洁高效: 业务逻辑清晰,直接针对ID进行操作,减少了数据传输和对象实例化开销。
  • 资源利用: 不需要将整个实体对象从数据库加载到内存中,尤其对于包含大量字段或关联对象的实体,能节省内存资源。

缺点:

  • 业务校验: 如果在删除前需要基于实体对象的某些属性进行复杂业务逻辑校验(例如,检查订单状态、用户权限等),则需要额外在服务层进行一次查询来获取这些属性,或者在删除前放弃这些校验。然而,对于大多数简单的删除操作,权限校验通常基于用户角色和资源ID即可完成。

适用场景:

  • 绝大多数的删除操作,尤其当删除操作不需要对实体模型的完整状态进行复杂业务判断时。

2.2 策略二:先加载模型再删除

流程:View (ID) -> Controller (ID) -> Service (ID) -> DAO (SELECT by ID) -> Service (Model) -> DAO (DELETE Model) -> DB

优点:

  • 完整性校验: 允许在删除前对实体模型的完整状态进行业务逻辑校验。例如,检查某个订单是否已支付,如果已支付则不允许删除。
  • Hibernate/JPA集成: 如果使用Hibernate/JPA的session.delete(entity)方法,需要传入一个持久化或游离态的实体对象。此策略自然地满足了这一要求。

缺点:

  • 性能下降: 至少需要执行两次数据库操作:一次SELECT查询以加载实体,一次DELETE操作以删除实体。这会增加数据库负担和响应时间。
  • 资源消耗: 需要将完整的实体对象加载到内存中,增加了内存消耗。

适用场景:

  • 删除前必须对实体对象的完整状态进行复杂业务逻辑校验的特定场景。例如,一个删除操作的有效性取决于该实体对象的多个非ID属性。

3. 最佳实践与建议

综合来看,对于大多数删除操作,直接通过ID删除是更推荐的最佳实践。它在性能和简洁性上具有明显优势。关于“应该在层之间传递模型而不是参数”的观点,这并非绝对。在创建或更新操作中,传递完整的模型是合理的,因为需要修改或持久化其所有属性。但对于仅需通过ID即可完成的查询或删除操作,传递ID参数更为高效和恰当。

示例代码(概念性):

// Controller层
@RestController
@RequestMapping("/api/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    @DeleteMapping("/{id}")
    public ResponseEntity deleteProduct(@PathVariable Long id) {
        // 在控制器层可以进行基本的输入验证
        if (id == null || id <= 0) {
            return ResponseEntity.badRequest().build();
        }
        productService.deleteProductById(id);
        return ResponseEntity.noContent().build();
    }
}

// Service层
@Service
public class ProductService {

    @Autowired
    private ProductDao productDao;

    @Transactional // 确保删除操作在事务中执行
    public void deleteProductById(Long id) {
        // 在服务层进行业务逻辑和权限校验
        // 例如:检查用户是否有权限删除此产品
        // if (!userService.hasPermissionToDelete(id, currentUser)) {
        //     throw new AccessDeniedException("No permission to delete this product.");
        // }

        // 业务校验(如果需要,可能在此处先查询部分信息,但尽量避免加载整个实体)
        // Product product = productDao.findById(id);
        // if (product == null) {
        //     throw new ResourceNotFoundException("Product not found with id: " + id);
        // }
        // if (product.isPublished()) {
        //     throw new IllegalStateException("Cannot delete a published product.");
        // }

        productDao.deleteById(id);
    }
}

// DAO层
@Repository
public class ProductDao {

    @PersistenceContext
    private EntityManager entityManager;

    public void deleteById(Long id) {
        // 使用JPQL或原生SQL直接通过ID删除
        // 这种方式效率最高,只执行一条DELETE语句
        int deletedCount = entityManager.createQuery("DELETE FROM Product p WHERE p.id = :id")
                                     .setParameter("id", id)
                                     .executeUpdate();
        if (deletedCount == 0) {
            // 可以选择抛出异常或记录日志,表示未找到要删除的实体
            // throw new ResourceNotFoundException("Product not found with id: " + id);
        }

        // 如果必须使用session.delete(entity) (不推荐用于简单删除)
        // Product product = entityManager.find(Product.class, id); // 执行SELECT
        // if (product != null) {
        //     entityManager.remove(product); // 执行DELETE
        // }
    }
}

4. 注意事项与总结

  1. 事务管理: 确保删除操作在事务中执行,以保证数据的一致性。Spring的@Transactional注解是实现这一点的便捷方式。
  2. 权限与业务校验: 即使采用直接ID删除,也务必在服务层进行严格的权限校验和必要的业务逻辑校验。例如,验证当前用户是否有权删除指定ID的记录。
  3. 错误处理: 如果尝试删除一个不存在的ID,DAO层可能不会有任何记录被删除。服务层应妥善处理这种情况,例如抛出ResourceNotFoundException。
  4. 软删除 vs. 硬删除: 在实际项目中,很多时候会采用“软删除”策略,即不真正从数据库删除记录,而是通过更新一个deleted或status字段来标记记录为已删除。这种情况下,无论哪种删除策略,最终都是一个UPDATE操作。
  5. ORM工具的灵活性: Hibernate/JPA提供了多种删除方式。EntityManager.remove(entity)需要一个托管状态的实体,而通过JPQL/HQL或Criteria API直接执行DELETE语句则更为灵活和高效。

综上所述,在Spring MVC和Hibernate应用中,当删除操作仅依赖于记录ID且无需对实体完整状态进行复杂业务校验时,直接通过ID进行删除是最佳实践。它能够有效提升系统性能,简化代码逻辑,并更好地适应大规模应用的需求。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

114

2025.08.06

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

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

29

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 在持久层开发中的核心技能。

35

2025.09.02

Hibernate框架搭建
Hibernate框架搭建

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

65

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、使用会话管理中间件。

748

2023.10.18

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

73

2026.01.28

热门下载

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

精品课程

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

共23课时 | 2.9万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

Java 教程
Java 教程

共578课时 | 52.4万人学习

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

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