当前位置: 首页 > article >正文

Spring Data JPA 高级特性

Spring Data JPA 高级特性引言大家好今天想和大家聊聊 Spring Data JPA 的高级特性。作为一名 Java 架构师我深知数据访问层对于应用的重要性。Spring Data JPA 是 Spring 生态中用于简化数据访问的优秀框架它提供了丰富的功能和灵活的配置选项。在本文中我将详细介绍 Spring Data JPA 的高级特性并通过实际案例展示如何在项目中应用这些特性。核心特性1. 自定义查询方法特点基于方法名自动生成查询支持复杂的查询条件提供灵活的参数绑定支持排序和分页示例代码Repository public interface UserRepository extends JpaRepositoryUser, Long { // 基于方法名自动生成查询 ListUser findByAgeGreaterThan(int age); // 支持多个条件 ListUser findByLastNameAndFirstName(String lastName, String firstName); // 支持排序 ListUser findByAgeGreaterThanOrderByLastNameAsc(int age); // 支持分页 PageUser findByLastName(String lastName, Pageable pageable); // 支持模糊查询 ListUser findByEmailContaining(String email); } // 使用示例 Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public ListUser getUsersByAge(int age) { return userRepository.findByAgeGreaterThan(age); } public PageUser getUsersByLastName(String lastName, int page, int size) { Pageable pageable PageRequest.of(page, size, Sort.by(firstName)); return userRepository.findByLastName(lastName, pageable); } }2. 自定义查询语句特点使用 Query 注解定义自定义查询支持 JPQL 和原生 SQL支持参数绑定支持复杂的查询逻辑示例代码Repository public interface UserRepository extends JpaRepositoryUser, Long { // 使用 JPQL Query(SELECT u FROM User u WHERE u.age :age) ListUser findUsersByAgeGreaterThan(Param(age) int age); // 使用原生 SQL Query(value SELECT * FROM users WHERE email LIKE %:email%, nativeQuery true) ListUser findUsersByEmailLike(Param(email) String email); // 支持更新操作 Modifying Query(UPDATE User u SET u.lastName :lastName WHERE u.id :id) int updateLastNameById(Param(lastName) String lastName, Param(id) Long id); // 支持删除操作 Modifying Query(DELETE FROM User u WHERE u.age :age) int deleteUsersByAgeLessThan(Param(age) int age); } // 使用示例 Service Transactional public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public int updateUserLastName(Long id, String lastName) { return userRepository.updateLastNameById(lastName, id); } public int deleteUsersByAge(int age) { return userRepository.deleteUsersByAgeLessThan(age); } }3. 实体图特点支持实体关联的预加载减少 N1 查询问题提供灵活的关联加载策略提高查询性能示例代码// 定义实体图 Entity NamedEntityGraph(name User.withOrders, attributeNodes NamedAttributeNode(orders)) public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String firstName; private String lastName; private int age; private String email; OneToMany(mappedBy user, cascade CascadeType.ALL) private ListOrder orders; // getters and setters } Entity public class Order { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String orderNumber; private double amount; ManyToOne JoinColumn(name user_id) private User user; // getters and setters } // 使用实体图 Repository public interface UserRepository extends JpaRepositoryUser, Long { EntityGraph(value User.withOrders, type EntityGraph.EntityGraphType.LOAD) ListUser findByLastName(String lastName); } // 使用示例 Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public ListUser getUsersWithOrders(String lastName) { return userRepository.findByLastName(lastName); } }4. 审计功能特点自动记录实体的创建和修改时间自动记录实体的创建者和修改者支持自定义审计字段提供审计信息的查询示例代码// 启用审计 SpringBootApplication EnableJpaAuditing public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } // 审计实体 Entity public class User implements AuditableString, Long { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String firstName; private String lastName; private int age; private String email; CreatedDate private LocalDateTime createdDate; LastModifiedDate private LocalDateTime lastModifiedDate; CreatedBy private String createdBy; LastModifiedBy private String lastModifiedBy; // getters and setters } // 实现 AuditorAware Component public class SpringSecurityAuditorAware implements AuditorAwareString { Override public OptionalString getCurrentAuditor() { // 从 SecurityContext 获取当前用户 Authentication authentication SecurityContextHolder.getContext().getAuthentication(); if (authentication null || !authentication.isAuthenticated()) { return Optional.empty(); } return Optional.of(authentication.getName()); } } // 使用示例 Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public User createUser(User user) { return userRepository.save(user); } public User updateUser(Long id, User user) { User existingUser userRepository.findById(id).orElseThrow(() - new RuntimeException(User not found)); existingUser.setFirstName(user.getFirstName()); existingUser.setLastName(user.getLastName()); existingUser.setAge(user.getAge()); existingUser.setEmail(user.getEmail()); return userRepository.save(existingUser); } }5. 规范Specifications特点支持动态查询条件提供类型安全的查询构建支持复杂的查询逻辑提高代码的可重用性示例代码// 实现 JpaSpecificationExecutor Repository public interface UserRepository extends JpaRepositoryUser, Long, JpaSpecificationExecutorUser { } // 定义规范 public class UserSpecifications { public static SpecificationUser hasAgeGreaterThan(int age) { return (root, query, criteriaBuilder) - criteriaBuilder.greaterThan(root.get(age), age); } public static SpecificationUser hasLastName(String lastName) { return (root, query, criteriaBuilder) - criteriaBuilder.equal(root.get(lastName), lastName); } public static SpecificationUser hasEmailLike(String email) { return (root, query, criteriaBuilder) - criteriaBuilder.like(root.get(email), % email %); } } // 使用示例 Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public ListUser getUsersByCriteria(int age, String lastName, String email) { SpecificationUser spec Specification.where(null); if (age 0) { spec spec.and(UserSpecifications.hasAgeGreaterThan(age)); } if (lastName ! null !lastName.isEmpty()) { spec spec.and(UserSpecifications.hasLastName(lastName)); } if (email ! null !email.isEmpty()) { spec spec.and(UserSpecifications.hasEmailLike(email)); } return userRepository.findAll(spec); } }实践案例1. 复杂查询场景实现复杂的查询逻辑包括多条件筛选、排序和分页。实现Repository public interface UserRepository extends JpaRepositoryUser, Long, JpaSpecificationExecutorUser { // 基于方法名的查询 PageUser findByAgeGreaterThan(int age, Pageable pageable); // 自定义查询 Query(SELECT u FROM User u WHERE u.lastName :lastName AND u.age :age) ListUser findByLastNameAndAgeGreaterThan(Param(lastName) String lastName, Param(age) int age); } Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public PageUser getUsers(int age, int page, int size, String sortBy, String sortDirection) { Sort sort Sort.by(Sort.Direction.fromString(sortDirection), sortBy); Pageable pageable PageRequest.of(page, size, sort); return userRepository.findByAgeGreaterThan(age, pageable); } public ListUser getUsersByLastNameAndAge(String lastName, int age) { return userRepository.findByLastNameAndAgeGreaterThan(lastName, age); } public ListUser getUsersByDynamicCriteria(UserCriteria criteria) { SpecificationUser spec Specification.where(null); if (criteria.getAge() ! null) { spec spec.and((root, query, cb) - cb.greaterThan(root.get(age), criteria.getAge())); } if (criteria.getLastName() ! null) { spec spec.and((root, query, cb) - cb.equal(root.get(lastName), criteria.getLastName())); } if (criteria.getEmail() ! null) { spec spec.and((root, query, cb) - cb.like(root.get(email), % criteria.getEmail() %)); } return userRepository.findAll(spec); } } public class UserCriteria { private Integer age; private String lastName; private String email; // getters and setters }2. 关联查询优化场景优化关联查询减少 N1 查询问题。实现// 使用实体图 Entity NamedEntityGraph(name User.withOrdersAndItems, attributeNodes { NamedAttributeNode(value orders, subgraph ordersWithItems) }, subgraphs { NamedSubgraph(name ordersWithItems, attributeNodes NamedAttributeNode(items)) }) public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String firstName; private String lastName; OneToMany(mappedBy user, cascade CascadeType.ALL) private ListOrder orders; // getters and setters } Entity public class Order { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String orderNumber; ManyToOne JoinColumn(name user_id) private User user; OneToMany(mappedBy order, cascade CascadeType.ALL) private ListOrderItem items; // getters and setters } Entity public class OrderItem { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String productName; private double price; private int quantity; ManyToOne JoinColumn(name order_id) private Order order; // getters and setters } Repository public interface UserRepository extends JpaRepositoryUser, Long { EntityGraph(value User.withOrdersAndItems, type EntityGraph.EntityGraphType.LOAD) ListUser findByLastName(String lastName); } Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public ListUser getUsersWithOrdersAndItems(String lastName) { return userRepository.findByLastName(lastName); } }3. 批量操作场景实现批量插入、更新和删除操作提高性能。实现Repository public interface UserRepository extends JpaRepositoryUser, Long { // 批量删除 Modifying Query(DELETE FROM User u WHERE u.age :age) int deleteUsersByAgeLessThan(Param(age) int age); // 批量更新 Modifying Query(UPDATE User u SET u.lastName :lastName WHERE u.id IN :ids) int updateLastNamesByIds(Param(lastName) String lastName, Param(ids) ListLong ids); } Service Transactional public class UserService { private final UserRepository userRepository; private final EntityManager entityManager; public UserService(UserRepository userRepository, EntityManager entityManager) { this.userRepository userRepository; this.entityManager entityManager; } // 批量插入 public void batchCreateUsers(ListUser users) { for (int i 0; i users.size(); i) { entityManager.persist(users.get(i)); if (i % 50 0) { entityManager.flush(); entityManager.clear(); } } entityManager.flush(); entityManager.clear(); } // 批量删除 public int batchDeleteUsersByAge(int age) { return userRepository.deleteUsersByAgeLessThan(age); } // 批量更新 public int batchUpdateUsers(ListLong ids, String lastName) { return userRepository.updateLastNamesByIds(lastName, ids); } }最佳实践1. 查询优化最佳实践使用实体图减少 N1 查询合理使用索引避免在循环中执行查询使用分页减少内存占用优化复杂查询的执行计划示例代码// 使用实体图 Repository public interface UserRepository extends JpaRepositoryUser, Long { EntityGraph(value User.withOrders, type EntityGraph.EntityGraphType.LOAD) ListUser findByLastName(String lastName); } // 使用分页 Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository userRepository; } public PageUser getUsers(int page, int size) { Pageable pageable PageRequest.of(page, size, Sort.by(lastName)); return userRepository.findAll(pageable); } }2. 事务管理最佳实践合理设置事务边界使用 Transactional 注解选择合适的事务隔离级别处理事务异常避免长事务示例代码Service public class UserService { private final UserRepository userRepository; private final OrderRepository orderRepository; public UserService(UserRepository userRepository, OrderRepository orderRepository) { this.userRepository userRepository; this.orderRepository orderRepository; } Transactional public User createUserWithOrder(User user, Order order) { // 保存用户 User savedUser userRepository.save(user); // 设置订单关联 order.setUser(savedUser); orderRepository.save(order); return savedUser; } Transactional(rollbackFor Exception.class) public void updateUser(Long id, User user) { User existingUser userRepository.findById(id).orElseThrow(() - new RuntimeException(User not found)); existingUser.setFirstName(user.getFirstName()); existingUser.setLastName(user.getLastName()); existingUser.setAge(user.getAge()); existingUser.setEmail(user.getEmail()); userRepository.save(existingUser); } }3. 性能优化最佳实践使用二级缓存批量操作延迟加载合理使用锁定策略监控查询性能示例代码// 启用二级缓存 Entity Cacheable public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String firstName; private String lastName; // getters and setters } // 批量操作 Service Transactional public class UserService { private final UserRepository userRepository; private final EntityManager entityManager; public UserService(UserRepository userRepository, EntityManager entityManager) { this.userRepository userRepository; this.entityManager entityManager; } public void batchCreateUsers(ListUser users) { for (int i 0; i users.size(); i) { entityManager.persist(users.get(i)); if (i % 50 0) { entityManager.flush(); entityManager.clear(); } } entityManager.flush(); entityManager.clear(); } }总结Spring Data JPA 提供了丰富的高级特性包括自定义查询方法、自定义查询语句、实体图、审计功能和规范等。这些特性不仅简化了数据访问层的开发还提高了应用的性能和可维护性。这其实可以更优雅一点。在实际项目中我们应该根据具体的业务需求合理运用这些高级特性以构建出高质量的数据访问层。同时我们也应该关注 Spring Data JPA 的发展及时了解和应用新的特性和最佳实践。如果您有任何问题或建议欢迎在评论区留言我会一一回复。参考资料Spring Data JPA DocumentationJPA SpecificationHibernate DocumentationSpring Boot DocumentationJava Persistence with Spring Data and Hibernate

相关文章:

Spring Data JPA 高级特性

Spring Data JPA 高级特性 引言 大家好,今天想和大家聊聊 Spring Data JPA 的高级特性。作为一名 Java 架构师,我深知数据访问层对于应用的重要性。 Spring Data JPA 是 Spring 生态中用于简化数据访问的优秀框架,它提供了丰富的功能和灵活…...

OpenClaw剪藏工具:Qwen3-VL:30B分类保存网页内容到Flomo

OpenClaw剪藏工具:Qwen3-VL:30B分类保存网页内容到Flomo 1. 为什么需要智能剪藏工具 作为一个每天要处理大量信息的开发者,我长期被碎片化知识管理问题困扰。浏览器收藏夹里堆积着上千个未分类的网页,微信收藏夹里塞满来不及整理的截图&…...

解码像素,探寻隐匿——CTF-03图片隐写学习心得

CTF-03聚焦图片隐写专项学习,是从基础安全知识迈向数据隐藏与取证实战的重要进阶。通过本次学习,我系统掌握了图片隐写的核心原理、常见工具与实操技巧,不仅深化了对“数据隐匿”攻防思维的理解,更提升了对图片文件的深度分析与信…...

3个步骤解锁QQ音乐加密文件:QMCDecode让音乐重获自由

3个步骤解锁QQ音乐加密文件:QMCDecode让音乐重获自由 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac,qmc0,qmc3转mp3, mflac,mflac0等转flac),仅支持macOS,可自动识别到QQ音乐下载目录,默认转…...

Phi-4-Reasoning-Vision行业应用:制造业设备巡检图故障推理与维修建议生成

Phi-4-Reasoning-Vision行业应用:制造业设备巡检图故障推理与维修建议生成 1. 技术背景与价值 在制造业设备维护领域,传统的人工巡检方式存在效率低、主观性强、经验依赖严重等问题。Phi-4-Reasoning-Vision多模态大模型为这一场景带来了革命性的解决方…...

OWL ADVENTURE与Git协作:AI视觉项目的版本管理与团队开发实践

OWL ADVENTURE与Git协作:AI视觉项目的版本管理与团队开发实践 做AI视觉项目,尤其是用OWL ADVENTURE这类框架时,最头疼的往往不是模型调参,而是项目本身的管理。你有没有遇到过这种情况:同事改了一个配置文件&#xff…...

DanKoe 视频笔记:如何在7天内重置你的生活:概述与核心概念

在本节课中,我们将学习如何通过一个为期七天的系统性过程,重置你的生活状态,摆脱迷茫和低效,重新找回专注、清晰和前进的动力。我们将从理解大脑运作的比喻开始,逐步介绍具体的行动步骤。 你的大脑是一台运行生命游戏…...

自定义默认提示词:PandaWiki 问答 “一键贴合业务”,企业降本增效新方案

深耕企业数字化与知识管理 7 年,服务过数百家中大型企业,发现企业知识库普遍存在三大核心痛点:AI 问答泛化、风格混乱、效率低下、人力成本高。PandaWiki 的自定义默认提示词功能,搭配多平台客服 开源可控,为企业提供…...

Studio 3T 2026.6 (macOS, Linux, Windows) - MongoDB 的终极 GUI、IDE 和 客户端

Studio 3T 2026.6 (macOS, Linux, Windows) - MongoDB 的终极 GUI、IDE 和 客户端 The Ultimate GUI, IDE and client for MongoDB 请访问原文链接:https://sysin.org/blog/studio-3t/ 查看最新版。原创作品,转载请保留出处。 作者主页:sy…...

图像降噪避坑指南:为什么你的sym4小波处理效果不明显?

图像降噪避坑指南:为什么你的sym4小波处理效果不明显? 当你在深夜调试代码,反复对比sym4小波处理前后的图像时,屏幕上的像素似乎在对你冷笑——降噪效果远不如论文里展示的那般惊艳。这不是个例,在计算机视觉开发者社群…...

GIL-Free Python并发仅剩最后1%难题:我们用37小时逆向分析PyO3内存模型,找到共享引用计数的终极解法

第一章:GIL-Free Python并发的终极挑战与破局意义Python 的全局解释器锁(GIL)长期被视为多核 CPU 利用率的“天花板”。它确保同一时刻仅有一个线程执行 Python 字节码,虽简化了内存管理与 C 扩展开发,却在 CPU 密集型…...

SDMatte在智能硬件配套:嵌入式设备端Web服务裁剪、ARM64交叉编译与内存精简

SDMatte在智能硬件配套:嵌入式设备端Web服务裁剪、ARM64交叉编译与内存精简 1. 技术背景与挑战 在智能硬件领域,嵌入式设备通常面临资源受限的挑战: 计算能力有限:ARM架构处理器性能远低于服务器级GPU内存资源紧张:…...

mPLUG-Owl3-2B多模态交互工具效果展示:高精度图像理解+自然语言问答真实案例

mPLUG-Owl3-2B多模态交互工具效果展示:高精度图像理解自然语言问答真实案例 1. 开篇:多模态交互的全新体验 想象一下,你随手拍了一张照片,然后像和朋友聊天一样问:"这张图片里有什么有趣的东西?&quo…...

收藏!小白程序员必备:从零入门大模型,抢占职场新风口(含学习资源包)

收藏!小白程序员必备:从零入门大模型,抢占职场新风口(含学习资源包) CB Insights报告显示,AI智能体市场正爆发式增长,2024年融资达38亿美元。市场分为基础设施、通用应用和垂直应用三大板块&…...

nli-distilroberta-base算法优化:利用LSTM思想增强序列上下文建模

nli-distilroberta-base算法优化:利用LSTM思想增强序列上下文建模 1. 效果展示背景 在自然语言推理任务中,nli-distilroberta-base作为轻量级Transformer模型表现出色,但在处理长文本序列时仍面临挑战。传统Transformer架构的自注意力机制虽…...

OpenClaw时间管理:QwQ-32B驱动的智能日历优化

OpenClaw时间管理:QwQ-32B驱动的智能日历优化 1. 为什么需要AI助手管理日历? 去年我发现自己陷入了典型的"日历困境":每天要处理十几个会议邀约,手动协调时区差异,还要在碎片时间里塞进健身和学习计划。最…...

大模型小白程序员必看:收藏这份AI智能体学习路径与构建思路

大模型小白程序员必看:收藏这份AI智能体学习路径与构建思路 本文系统梳理AI智能体的概念、发展脉络与核心架构,清晰拆解其与传统工作流的本质差异,聚焦智能体三大核心组件(规划能力、记忆系统、工具使用机制)的技术细节…...

7.系统配置与性能评价

一、系统配置与性能评价 00:00 1. 考情分析 00:12 考查频率:本章节在历年真题中偶尔出现,非每年必考分值占比:若考查则占1-2分,分值较低内容稳定性:与旧版教材内容基本一致,无实质…...

5分钟快速上手:AnythingtoRealCharacters2511动漫图片转真人照片教程

5分钟快速上手:AnythingtoRealCharacters2511动漫图片转真人照片教程 1. 认识你的动漫转真人工具 1.1 工具能做什么? AnythingtoRealCharacters2511是一个专门将动漫图片转化为真人照片的AI工具。它基于Qwen-Image-Edit模型开发,特别擅长处…...

OpenClaw语音交互方案:Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF对接语音输入输出模块

OpenClaw语音交互方案:Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF对接语音输入输出模块 1. 为什么需要语音交互能力 去年冬天的一个深夜,我正蜷在沙发上调试一个自动化脚本,突然意识到——当双手被咖啡杯占据时,用语…...

VS Code + Flask新手避坑指南:从虚拟环境配置到第一个Hello World页面

VS Code Flask新手避坑指南:从虚拟环境配置到第一个Hello World页面 刚接触Flask框架的开发者常会遇到各种环境配置问题——虚拟环境切换失败、包导入报错、路由访问404……这些看似简单的坑往往让人耗费数小时。本文将用最小可行方案带你在VS Code中快速搭建Flas…...

腾讯地图API实战:5分钟搞定经纬度录入与地图选点功能(Vue版)

腾讯地图API实战:5分钟搞定经纬度录入与地图选点功能(Vue版) 在当今的Web开发中,地图功能已成为许多应用的标配需求。无论是电商平台的店铺定位,还是社交应用的位置分享,甚至是企业内部系统的区域管理&…...

终极指南:如何快速导出并永久保存微信聊天记录

终极指南:如何快速导出并永久保存微信聊天记录 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾担心更换手机后丢失宝贵的微信聊天记录?工…...

2023-2026热门网页游戏盘点|传奇页游稳居顶流,5大类型闭眼冲

近几年,电脑网页游戏凭借“无需下载、点开即玩”的便捷优势,依旧深受玩家喜爱,适配上班族、学生党等各类人群的碎片化娱乐需求。从复古传奇到策略竞技,从休闲解压到沉浸式MMO,各类热门页游百花齐放。今天,就…...

Capacitor插件避坑指南:Android/iOS双端自动更新那些踩过的坑

Capacitor跨平台自动更新实战:Android与iOS双端兼容性深度解析 移动应用开发中,自动更新功能是提升用户体验的关键环节。对于使用Capacitor框架的开发者而言,如何优雅处理Android和iOS平台的差异,成为技术实现的核心挑战。本文将…...

TMI8260SP的替代品7889直流双向电机驱动芯片详解

在直流电机驱动领域,TMI8260SP作为一款经典的双向马达驱动芯片,曾广泛应用于各类中低功率电机控制场景,其稳定的性能积累了良好的市场口碑。但随着市场对电机驱动芯片的性能、功耗及性价比要求不断提升,7889直流双向电机驱动芯片凭…...

EVA-01部署教程:Qwen2.5-VL-7B模型服务API封装+NERV风格响应协议

EVA-01部署教程:Qwen2.5-VL-7B模型服务API封装NERV风格响应协议 1. 引言:欢迎来到NERV指挥中心 想象一下,你面前有一个能“看懂”图片的智能助手,但它不是普通的聊天窗口,而是一个充满未来感的机甲驾驶舱。紫色的装甲…...

【obs studio】从零开始:高效录制屏幕与声音的完整指南

1. 为什么选择OBS Studio录制屏幕与声音? 如果你正在寻找一款免费、开源且功能强大的屏幕录制工具,OBS Studio绝对是你的不二之选。我最初接触这款软件是因为需要录制一些技术教程,试过市面上不少付费软件后,发现OBS Studio不仅完…...

SAM 3入门到应用:从图片分割到视频跟踪完整指南

SAM 3入门到应用:从图片分割到视频跟踪完整指南 1. SAM 3简介与核心能力 SAM 3(Segment Anything Model 3)是Facebook推出的新一代图像和视频分割模型,它通过统一的基础架构实现了前所未有的通用分割能力。与传统的专用分割模型…...

Python 函数式编程利器:Partial 与 ParamSpec 技术解析

partial 是 Python functools 模块中的偏函数,核心作用是「冻结」一个函数的部分参数(位置参数或关键字参数),生成一个新的函数,新函数调用时只需传入剩余未被冻结的参数即可,无需重复传入固定参数&#xf…...