MyBatis关联映射深度解析:从<collection>与<association>到性能优化实战
1. 项目概述为什么我们需要关注MyBatis的关联映射如果你用过MyBatis肯定遇到过这样的场景查询一个订单需要顺带把订单里的所有商品项也查出来或者反过来查询一个商品项需要知道它属于哪个订单。这就是典型的一对多和多对一关系。在数据库里我们用外键来维系这种关系但在Java对象的世界里我们希望得到的是一个结构清晰、嵌套完整的对象树。MyBatis的collection和association标签就是连接数据库表关系与Java对象关系的桥梁。很多开发者尤其是刚接触MyBatis的朋友对这两个标签的使用往往停留在“复制粘贴”阶段。配置文件写出来了数据也能查出来但一旦遇到N1查询问题、复杂的嵌套结果映射或者性能瓶颈就有点束手无策。更别提去理解MyBatis底层是如何组装这些关联数据的。这次我们不只讲怎么用更要拆开揉碎了讲清楚背后的原理、不同写法的优劣以及我在实际项目中踩过的那些坑。我会用一个贯穿始终的“博客系统”案例来演示这个案例包含用户、文章、评论关系清晰非常贴近实际开发。2. 核心概念与模型设计建立清晰的领域认知在深入代码之前我们必须先把业务模型和数据库设计理清楚。模糊的领域认知是导致后续映射混乱的根源。2.1 案例业务模型定义我们模拟一个简单的博客系统核心实体有三个用户User系统的作者。文章Article用户发表的内容。评论Comment用户对文章的回复。它们之间的关系是一个用户可以写多篇文章。这是一对多关系User - ListArticle。一篇文章属于一个用户。这是多对一关系Article - User。一篇文章可以有多条评论。这是一对多关系Article - ListComment。一条评论属于一篇文章同时也由一个用户发表。这是两个多对一关系Comment - Article, Comment - User。2.2 数据库表结构设计根据上述模型我们设计三张表-- 用户表 CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键ID, username VARCHAR(50) NOT NULL COMMENT 用户名, email VARCHAR(100) COMMENT 邮箱 ); -- 文章表 CREATE TABLE article ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键ID, user_id BIGINT NOT NULL COMMENT 作者ID外键关联user.id, title VARCHAR(200) NOT NULL COMMENT 文章标题, content TEXT COMMENT 文章内容, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, FOREIGN KEY (user_id) REFERENCES user(id) ); -- 评论表 CREATE TABLE comment ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键ID, article_id BIGINT NOT NULL COMMENT 文章ID外键关联article.id, user_id BIGINT NOT NULL COMMENT 评论者ID外键关联user.id, content TEXT NOT NULL COMMENT 评论内容, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 评论时间, FOREIGN KEY (article_id) REFERENCES article(id), FOREIGN KEY (user_id) REFERENCES user(id) );2.3 Java实体类设计与表结构对应我们创建Java实体类。这里的关键是实体类的属性要能体现对象间的关联关系。User.java (用户实体)public class User { private Long id; private String username; private String email; // 一对多一个用户拥有多篇文章 private ListArticle articles; // 一对多一个用户发表过多条评论根据业务需求可选 private ListComment comments; // 构造方法、getter、setter省略... }Article.java (文章实体)public class Article { private Long id; private String title; private String content; private Date createTime; // 多对一一篇文章属于一个用户 private User author; // 一对多一篇文章有多条评论 private ListComment commentList; // 构造方法、getter、setter省略... }Comment.java (评论实体)public class Comment { private Long id; private String content; private Date createTime; // 多对一一条评论属于一篇文章 private Article article; // 多对一一条评论由一个用户发表 private User commentUser; // 构造方法、getter、setter省略... }注意实体类中的集合如ListArticle和对象属性如User author就是我们需要用MyBatis关联映射来填充的。数据库查回来的扁平化结果集MyBatis会根据我们的配置自动“折叠”成这种嵌套的对象树。3. 多对一association映射详解与实战多对一关系在查询中是更常见的一方。比如查文章时带上作者信息查评论时带上评论者和文章概要。association标签就是用来处理这种“一个对象内部包含另一个对象”的场景。3.1association的两种配置方式MyBatis提供了两种主流配置方式嵌套结果映射ResultMap和嵌套查询Nested Select。两者各有优劣适用场景不同。3.1.1 方式一嵌套结果映射推荐用于关联数据一次性查询这是性能最好、也是最常用的方式。通过单条SQL联表查询一次性获取所有数据然后通过resultMap描述复杂的映射关系。目标查询文章详情并包含作者User的完整信息。ArticleMapper.xml 配置!-- 1. 定义包含关联的完整结果映射 -- resultMap idArticleWithAuthorResultMap typeArticle !-- 映射文章自身字段 -- id propertyid columnid/ result propertytitle columntitle/ result propertycontent columncontent/ result propertycreateTime columncreate_time/ !-- 2. 使用 association 映射“多对一”的作者对象 -- !-- property: Article实体类中的属性名即 author -- !-- javaType: 该属性的Java类型 -- !-- 内部使用 result 子标签映射 User 的字段 -- association propertyauthor javaTypeUser id propertyid columnuser_id/ !-- 注意column 对应查询结果中的列名 -- result propertyusername columnusername/ result propertyemail columnuser_email/ !-- 别名避免列名冲突 -- /association /resultMap !-- 3. 编写联表查询SQL并使用上面定义的 resultMap -- select idselectArticleWithAuthorById resultMapArticleWithAuthorResultMap SELECT a.id, a.title, a.content, a.create_time, a.user_id, -- 文章表的外键也是用户表的主键 u.username, u.email AS user_email -- 使用别名避免与后续可能出现的其他email列冲突 FROM article a LEFT JOIN user u ON a.user_id u.id WHERE a.id #{id} /select关键点解析列名与别名联表查询时如果多张表有相同列名如idMyBatis在映射时会混淆。必须为重复的列或需要特殊标识的列设置别名。上面我们将u.email别名为了user_email。id标签的重要性在association内部指定id propertyid columnuser_id至关重要。MyBatis利用这个标识符来对关联对象进行去重。如果多篇文章是同一个作者MyBatis通过这个id能识别出是同一个User对象从而避免创建重复实例。联表选择这里使用了LEFT JOIN即使文章没有对应的作者理论上不应该文章数据也会被查询出来作者属性为null。根据业务需求也可以使用INNER JOIN。实操心得对于这种确定性的、需要同时展示的关联数据如文章和作者强烈推荐使用嵌套结果映射。一条SQL搞定数据库优化方便没有额外的网络开销是性能最优解。3.1.2 方式二嵌套查询适用于关联数据可选或动态加载嵌套查询的方式是先执行主查询然后根据主查询结果中的某一列通常是外键再去执行另一个查询来获取关联对象。ArticleMapper.xml 配置!-- 1. 首先需要一个根据ID查询User的映射语句 -- select idselectUserById resultTypeUser SELECT id, username, email FROM user WHERE id #{id} /select !-- 2. 定义Article的结果映射association通过select属性引用另一个查询 -- resultMap idArticleWithAuthorNestedSelectMap typeArticle id propertyid columnid/ result propertytitle columntitle/ result propertycontent columncontent/ result propertycreateTime columncreate_time/ !-- property: Article中的author属性 column: 将当前查询结果中的user_id列的值作为参数传递给selectUserById select: 指定要执行的嵌套查询语句的ID -- association propertyauthor columnuser_id selectselectUserById/ /resultMap !-- 3. 主查询只查Article表 -- select idselectArticleWithAuthorByIdNested resultMapArticleWithAuthorNestedSelectMap SELECT id, title, content, create_time, user_id FROM article WHERE id #{id} /select执行逻辑MyBatis首先执行selectArticleWithAuthorByIdNested得到一条Article记录。然后发现association配置它会取出这条记录的user_id值去执行selectUserById查询并将结果赋值给Article对象的author属性。警告N1查询问题嵌套查询最大的坑就是N1查询问题。如果主查询返回N条文章那么为了获取每篇文章的作者会额外执行N次selectUserById查询。总共执行1主查询 N关联查询次SQL性能在数据量大时是灾难性的。什么情况下可以用关联数据不是每次都需要延迟加载。主查询结果集很小比如最多几十条。关联查询本身非常复杂不适合写在联表SQL中。MyBatis提供了fetchType属性来控制加载行为association propertyauthor columnuser_id selectselectUserById fetchTypelazy/设置为lazy后只有当你真正访问article.getAuthor()时MyBatis才会去执行嵌套查询。这需要全局配置中开启延迟加载。我的建议默认情况下优先使用嵌套结果映射联表查询。除非你非常清楚嵌套查询带来的性能影响并且有明确的延迟加载需求否则不要轻易使用。3.2 处理多个多对一关系评论Comment对象关联了文章和用户两个对象是演示多重association的绝佳例子。目标查询评论时同时获取评论对应的文章简要信息如标题和评论者的信息。CommentMapper.xml 配置使用嵌套结果映射resultMap idCommentWithArticleAndUserResultMap typeComment id propertyid columncid/ !-- 评论ID -- result propertycontent columncontent/ result propertycreateTime columncomment_create_time/ !-- 关联文章对象 -- association propertyarticle javaTypeArticle id propertyid columnaid/ !-- 文章ID -- result propertytitle columntitle/ !-- 这里不需要文章的全部内容只取标题即可 -- /association !-- 关联用户对象评论者 -- association propertycommentUser javaTypeUser id propertyid columnuid/ !-- 用户ID -- result propertyusername columncomment_username/ /association /resultMap select idselectCommentDetailById resultMapCommentWithArticleAndUserResultMap SELECT c.id AS cid, c.content, c.create_time AS comment_create_time, a.id AS aid, a.title, u.id AS uid, u.username AS comment_username FROM comment c LEFT JOIN article a ON c.article_id a.id LEFT JOIN user u ON c.user_id u.id WHERE c.id #{id} /select注意事项别名管理当三张表联查时列名冲突的可能性更大。必须为每个id和可能重复的列如username设置清晰的别名并在resultMap中准确引用。良好的别名习惯如表名_字段名或用途_字段名能极大减少映射错误。选择性映射association内部不需要映射关联对象的全部字段。像上面的Article我们只关心id和title这能减少不必要的数据传输和对象构造开销。4. 一对多collection映射详解与实战一对多关系是另一个核心场景比如查看用户主页时列出其所有文章或者查看文章时展示其所有评论。collection标签就是用来映射这种“一个对象包含一个对象集合”的关系。4.1collection的两种配置方式与association类似collection也支持嵌套结果映射和嵌套查询。4.1.1 方式一嵌套结果映射处理一对多结果集折叠这是处理一对多最经典也稍复杂的方式。SQL联表查询会返回多行数据例如一个用户对应多篇文章查询会返回用户数据重复的多行MyBatis需要根据主对象的ID将这些行“折叠”成一个对象及其集合。目标查询用户及其发表的所有文章。UserMapper.xml 配置!-- 1. 定义包含集合的结果映射 -- resultMap idUserWithArticlesResultMap typeUser !-- 映射用户自身字段 -- id propertyid columnuid/ !-- 核心主对象的id -- result propertyusername columnusername/ result propertyemail columnemail/ !-- 2. 使用 collection 映射“一对多”的文章集合 -- !-- ofType: 指定集合中元素的Java类型 -- collection propertyarticles ofTypeArticle id propertyid columnaid/ !-- 集合元素的id用于去重 -- result propertytitle columntitle/ result propertycontent columncontent/ result propertycreateTime columnarticle_create_time/ !-- 注意这里通常不需要再嵌套映射文章的author否则会形成循环引用 -- /collection /resultMap !-- 3. 编写联表查询SQL -- select idselectUserWithArticlesById resultMapUserWithArticlesResultMap SELECT u.id AS uid, u.username, u.email, a.id AS aid, a.title, a.content, a.create_time AS article_create_time FROM user u LEFT JOIN article a ON u.id a.user_id WHERE u.id #{userId} /selectMyBatis的“折叠”算法解析 这是理解一对多嵌套结果映射的关键。当我们执行上面的SQL数据库可能返回如下数据uidusernameemailaidtitlearticle_create_time1张三zhangsanexample.com101MyBatis入门2023-10-011张三zhangsanexample.com102Spring实战2023-10-05MyBatis在遍历结果集时首先看到第一行根据uid1创建一个User对象并初始化一个空的ListArticle。将第一行的文章数据id101创建一个Article对象加入到这个User的articles列表中。移动到第二行发现uid还是1它知道这是同一个User对象通过id columnuid判断。于是不再创建新的User对象而是将第二行的文章数据id102创建为另一个Article对象追加到同一个User对象的articles列表中。最终我们得到一个User对象其articles列表包含两篇文章。实操心得确保主对象User的id映射正确是collection能正常工作的前提。这个id是MyBatis识别行是否属于同一个主对象的依据。4.1.2 方式二嵌套查询及其严重性能问题与association类似collection也可以使用嵌套查询。UserMapper.xml 配置!-- 先定义查询用户文章列表的语句 -- select idselectArticlesByUserId resultTypeArticle SELECT id, title, content, create_time FROM article WHERE user_id #{userId} /select resultMap idUserWithArticlesNestedSelectMap typeUser id propertyid columnid/ result propertyusername columnusername/ result propertyemail columnemail/ !-- columnid 将用户的id传给嵌套查询 -- collection propertyarticles columnid ofTypeArticle selectselectArticlesByUserId/ /resultMap select idselectUserWithArticlesByIdNested resultMapUserWithArticlesNestedSelectMap SELECT id, username, email FROM user WHERE id #{userId} /select性能警示这种方式同样存在N1查询问题而且对于一对多问题可能更严重。如果主查询返回N个用户每个用户有M篇文章那么总查询次数是 1 N * M不对实际上是1主查询 N每个用户触发一次selectArticlesByUserId。虽然每个嵌套查询可能返回多行但数据库交互次数仍然是N1次当用户量很大时性能开销巨大。结论对于一对多查询嵌套结果映射联表查询通常是唯一可行的选择除非你的数据量极小或者你明确使用了延迟加载并且关联数据访问频率很低。4.2 复杂嵌套多层级关联映射现实中的对象关系往往更复杂比如我们想查询一篇文章包含其作者信息以及文章下的所有评论而每条评论又包含评论者的信息。这就形成了多层级嵌套。目标查询文章详情包含作者以及文章下的所有评论每条评论包含评论者信息。ArticleMapper.xml 配置resultMap idArticleDetailResultMap typeArticle id propertyid columna_id/ result propertytitle columntitle/ result propertycontent columncontent/ result propertycreateTime columna_create_time/ !-- 多对一作者 -- association propertyauthor javaTypeUser id propertyid columnu_id/ result propertyusername columnauthor_name/ result propertyemail columnauthor_email/ /association !-- 一对多评论列表 -- collection propertycommentList ofTypeComment id propertyid columnc_id/ result propertycontent columncomment_content/ result propertycreateTime columnc_create_time/ !-- 评论内部又有一个多对一评论者 -- association propertycommentUser javaTypeUser id propertyid columncommenter_id/ result propertyusername columncommenter_name/ /association /collection /resultMap select idselectArticleDetailById resultMapArticleDetailResultMap SELECT a.id AS a_id, a.title, a.content, a.create_time AS a_create_time, u.id AS u_id, u.username AS author_name, u.email AS author_email, c.id AS c_id, c.content AS comment_content, c.create_time AS c_create_time, cu.id AS commenter_id, cu.username AS commenter_name FROM article a LEFT JOIN user u ON a.user_id u.id LEFT JOIN comment c ON a.id c.article_id LEFT JOIN user cu ON c.user_id cu.id WHERE a.id #{articleId} ORDER BY c.create_time ASC -- 对评论排序 /select这个查询的挑战与技巧笛卡尔积爆炸这是多表LEFT JOIN特别是多层一对多关联时最危险的问题。一篇文章有1个作者10条评论。联表后结果集行数 1 (作者) * 10 (评论) 10行。作者的信息在这10行中重复了10次。如果还有更多层嵌套数据冗余会呈指数级增长。列名别名至关重要三张表article, user(作者), user(评论者)都有id和username必须用有意义的别名如u_id,author_name,commenter_id,commenter_name严格区分。排序在SQL中使用ORDER BY对集合元素如评论进行排序可以保证在Java集合中元素的顺序符合预期。我的经验对于这种深度嵌套且数据量可能较大的查询需要非常谨慎。要评估结果集的行数。如果一篇文章有上百条评论查询返回的数据量就会很大。在实际项目中我们往往会采用分步查询或业务层组装的方式来替代这种复杂的单次联表查询以平衡复杂度和性能。5. 高级技巧、性能优化与避坑指南掌握了基本用法我们来看看如何用得更好、更稳。这些经验很多是文档里不会写的都是实践中踩坑踩出来的。5.1 延迟加载懒加载的配置与权衡延迟加载可以解决N1查询问题中的“立即加载”带来的性能损耗。它的核心思想是只有当你真正用到关联数据时MyBatis才发出SQL去查询。全局配置mybatis-config.xml 或 application.ymlsettings !-- 开启全局延迟加载开关 -- setting namelazyLoadingEnabled valuetrue/ !-- 将积极加载改为按需加载3.4.1版本后默认是false按需加载 -- setting nameaggressiveLazyLoading valuefalse/ /settings在映射文件中使用!-- 嵌套查询方式并指定为懒加载 -- association propertyauthor columnuser_id selectselectUserById fetchTypelazy/ collection propertyarticles columnid selectselectArticlesByUserId fetchTypelazy/注意事项与坑“懒加载”与“序列化”的冲突这是最常见的坑。当你开启懒加载后对象里包含的是MyBatis动态生成的代理对象。如果你将这个对象直接转换成JSON例如通过Spring MVC的ResponseBody返回给前端JSON序列化工具如Jackson在遍历对象属性时会触发代理对象的getter方法从而导致懒加载查询被执行这可能导致你期望的懒加载失效甚至引发意外的数据库查询和性能问题。解决方案使用DTOData Transfer Object来替代直接返回实体。在Service层将懒加载的实体对象转换为只包含所需字段的普通POJO DTO再返回给控制器。Session生命周期懒加载查询需要数据库连接SqlSession仍然存活。在Web应用中通常通过“Open Session In View”模式来保持Session直到视图渲染完成。但在非Web环境或自定义Session管理时如果Session提前关闭访问懒加载属性会抛出异常。性能权衡懒加载把一次大的联表查询拆成了多次小的查询。在关联数据访问概率低的情况下是优势但如果访问概率高反而会增加总的数据库交互次数和延迟。没有银弹需要根据具体场景分析。5.2 使用sql片段和include复用映射代码当多个查询结果映射有相同的字段集合时可以使用sql定义片段用include引入保持代码整洁。!-- 定义用户字段的SQL片段 -- sql iduserColumns id, username, email /sql !-- 定义用户结果映射的片段 -- sql iduserResultMap id propertyid columnid/ result propertyusername columnusername/ result propertyemail columnemail/ /sql !-- 在查询中使用 -- select idselectUserById resultTypeUser SELECT include refiduserColumns/ FROM user WHERE id #{id} /select !-- 在结果映射中使用 -- resultMap idSomeResultMap typeXxx ... association propertyuser javaTypeUser include refiduserResultMap/ /association ... /resultMap5.3 鉴别器discriminator的妙用这是一个高级但非常有用的功能用于根据某列的值决定如何映射不同的关联对象。典型的例子是一个消息表有系统消息、评论消息、点赞消息等类型它们关联的目标实体不同。假设我们有一个notification表其中type字段区分消息类型target_id关联不同表的主键。resultMap idNotificationResultMap typeNotification id propertyid columnid/ result propertycontent columncontent/ result propertytype columntype/ !-- 根据type字段的值决定如何映射target对象 -- discriminator javaTypeint columntype case value1 resultMapcommentNotificationMap/ !-- 评论消息 -- case value2 resultMaplikeNotificationMap/ !-- 点赞消息 -- /discriminator /resultMap resultMap idcommentNotificationMap typeCommentNotification extendsNotificationResultMap association propertytarget javaTypeComment selectselectCommentById columntarget_id/ /resultMap resultMap idlikeNotificationMap typeLikeNotification extendsNotificationResultMap association propertytarget javaTypeLike selectselectLikeById columntarget_id/ /resultMap5.4 常见问题排查与调试技巧映射失败属性为null检查点1列名与别名这是90%的问题所在。仔细核对SQL查询返回的列名与result/association/collection中的column属性是否完全一致包括大小写取决于数据库配置。检查点2属性名核对property属性与Java实体类的字段名是否一致。检查点3日志开启MyBatis的SQL日志设置日志级别为DEBUG查看实际执行的SQL和返回的结果集与你的映射配置逐列对比。一对多映射结果集合中对象重复原因collection中忘记指定集合元素对象的id。MyBatis需要id来对集合内的元素进行去重。解决确保在collection内部为集合元素类型如Article正确配置了id映射。嵌套查询导致N1问题性能慢识别观察日志是否执行了1条主查询和大量类似的子查询。解决评估是否能用嵌套结果映射联表替代。如果不能考虑是否真的需要所有数据或者使用延迟加载并确保不会在序列化时意外触发。复杂联表查询结果混乱原因多层一对多关联导致笛卡尔积数据冗余严重可能影响MyBatis的“折叠”逻辑。解决考虑拆分成多个简单的查询在Service层进行数据组装。或者使用MyBatis的ResultMap注解配合多个resultMap进行更精细的控制。循环引用StackOverflowError场景User里有ListArticleArticle里又有User author。当双向引用且都使用嵌套结果映射时JSON序列化或toString()方法可能导致无限递归。解决打破循环在某一方通常是多方的映射中不配置对另一方的关联。例如在Article的author映射中只映射id和name而不让author对象再拥有articles属性在查询时。使用DTO这是最根本的解决方案DTO根据视图需求设计天然避免了实体间的复杂循环引用。序列化注解使用Jackson的JsonIgnoreProperties注解在实体类上忽略对方的属性。关联映射是MyBatis的灵魂功能之一它强大但需要精心设计。理解其原理结果集折叠、嵌套查询触发比记住语法更重要。在简单的CRUD中使用它事半功倍在复杂的业务关联中则需要权衡联表查询的复杂度与多次查询的代价。记住没有最好的方案只有最适合当前场景的方案。从简单的嵌套结果映射开始在遇到性能瓶颈或特殊需求时再考虑延迟加载、分步查询等高级策略并始终将代码清晰性和可维护性放在重要位置。

相关新闻

Unity 2020安卓打包环境配置:JDK、SDK、NDK保姆级教程

Unity 2020安卓打包环境配置:JDK、SDK、NDK保姆级教程

1. 项目概述:为什么Unity打包APK会让人焦虑?如果你刚开始接触Unity,或者从Unity 2019升级到2020,准备把辛苦做好的游戏或应用打包成安卓APK时,大概率会卡在第一步:环境配置。那种感觉就像你兴冲冲地准备开车…

2026/8/4 5:56:23 阅读更多 →
【华为OD机试真题 新系统】1067、战士技能规划设计 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

【华为OD机试真题 新系统】1067、战士技能规划设计 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

文章目录 一、题目 🎃题目描述 🎃输入输出 🎃样例1 🎃样例2 🎃样例3 二、代码与思路参考 🎈C++语言思路 🎉C++代码 🎈Java语言思路 🎉Java代码 🎈Python语言思路 🎉Python代码 🎈C语言思路 🎉 C语言代码 🎈JS语言思路 🎉JS代码 作者:KJ.JK 订阅…

2026/8/4 5:56:23 阅读更多 →
Linux rcp 命令超全解析|远程文件复制用法 + 安全避坑指南

Linux rcp 命令超全解析|远程文件复制用法 + 安全避坑指南

一、命令简介rcp(remote copy)命令用于在本地主机与远程主机之间,或两台远程主机之间复制文件或目录。它基于 rsh(remote shell)协议实现,通过适当的配置可以实现无需密码的文件传输,旨在简化跨…

2026/8/4 5:55:22 阅读更多 →

最新新闻

SpringBoot医院信息管理系统(HIS)架构设计与实践

SpringBoot医院信息管理系统(HIS)架构设计与实践

1. 项目概述:医院信息管理系统的核心价值 医院信息管理系统(HIS)是医疗行业数字化转型的基础设施,这个基于SpringBoot的解决方案将传统纸质病历、手工排班和人工统计彻底升级为电子化流程。我在三甲医院信息化改造项目中亲历过从零…

2026/8/4 7:30:02 阅读更多 →
MCP、Skills、子Agent三件套,手把手教你搞定代码维护!

MCP、Skills、子Agent三件套,手把手教你搞定代码维护!

这三个词你可能都见过。MCP、Skills、子Agent——每篇 AI 编程的文章都在提,但看完还是分不清谁是谁、什么时候用哪个。 我用一个 C 项目把它们串起来讲。读完你会知道这三样东西分别解决什么问题、在什么场景下用哪个、以及三者的关系。 先别管定义,看一…

2026/8/4 7:30:02 阅读更多 →
Spring-ai-alibaba音频

Spring-ai-alibaba音频

文章目录Spring AI Alibaba 语音模型实战(TTS STT)版本一、依赖引入二、yml 配置三、代码案例:TTS(文字 → 音频)四、代码案例:STT(音频 → 文字)1. 公网 URL 同步 call()&#xf…

2026/8/4 7:30:02 阅读更多 →
从 PHP 到 AI + Golang,程序员自救转型手记(四十八):菜单规则管理实现

从 PHP 到 AI + Golang,程序员自救转型手记(四十八):菜单规则管理实现

这是一个系列 Blog,作者将以一个 PHP 全栈工程师的身份,利用 AI 工具(claude code、codex、deepseek、豆包等):从零开始学习 golang 语言,并最终完成 ai-go-admin(github | gitee)开…

2026/8/4 7:30:02 阅读更多 →
SQL Server日期时间函数全解析:从基础概念到高阶应用与性能优化

SQL Server日期时间函数全解析:从基础概念到高阶应用与性能优化

1. 项目概述:为什么你需要一份“最全”的日期时间函数指南干了这么多年数据库开发,我发现一个挺有意思的现象:无论是新手还是老手,但凡涉及到SQL Server里的日期时间处理,总免不了要去翻文档或者搜一下某个函数的具体用…

2026/8/4 7:30:02 阅读更多 →
B站视频下载终极指南:三步解锁大会员4K高清视频

B站视频下载终极指南:三步解锁大会员4K高清视频

B站视频下载终极指南:三步解锁大会员4K高清视频 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 还在为B站上的精彩视频无法…

2026/8/4 7:29:02 阅读更多 →

日新闻

AI Agent白手起家26: 使用标准事件驱动大模型实践

AI Agent白手起家26: 使用标准事件驱动大模型实践

纲要 练习目标:掌握大模型标准事件的调用回顾 LangChain 中的核心标准事件 invokestreambatchastream_eventswith_structured_output 环境准备实战代码:多种事件调用对比 同步调用与流式输出批量处理异步事件流监听结构化输出 运行说明与预期结果总结与扩…

2026/8/4 0:00:40 阅读更多 →
dealsea是什么?跨境卖家必知的美国deal站入门指南

dealsea是什么?跨境卖家必知的美国deal站入门指南

说实话,第一次听说美国这个老牌折扣网站的跨境卖家,十个有八个会问同一个问题:这个平台到底是干嘛的?我见过一个做家居出口的朋友,他在亚马逊上月销二十万美金,却从来没用过它。我给他看了首页——一屏一屏…

2026/8/4 0:01:40 阅读更多 →
清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

通讯作者:邓兵、刘建国通讯单位:清华大学DOI:https://doi.org/10.1021/acs.est.6c00603研究背景稀土元素(REEs)是清洁能源技术与电子器件不可或缺的核心原料,然而传统提取方式依赖能耗高、排放大的采矿与强…

2026/8/4 0:01:40 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/3 4:58:13 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/3 1:53:31 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/4 5:26:40 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/3 13:07:03 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/3 5:19:38 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/3 8:27:36 阅读更多 →