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

MyBatis中一对多关系的两种处理方法

目录

1.多表联查(通过collection标签的ofType属性)

1)mapper

2)mapper.xml

3)测试代码

4)测试结果

2.分布查询(通过collection标签的select属性)

1)mapper

2)mapper.xml

3)测试代码

4)测试结果

附录

1.Classes实体类

2.student类

3.OneToManyMapper

4.OneToManyMapper.xml

5.OneToManyMapperTest.xml

 6.sql

studentSql

classesSql


1.多表联查(通过collection标签的ofType属性)

1)mapper

/*** collectionBy ofType*/
Classes queryClassesAndStudentBycollection(@Param("id") int id);

2)mapper.xml

<!--collection-->
<resultMap id="collectionResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><!--collection--><collection property="students" ofType="org.xiji.enty.Student"><id property="sid" column="sid"/><result property="studentName" column="studentName"/><result property="studentAge" column="studentAge"/><result property="classId" column="cid"/></collection></resultMap>
<select id="queryClassesAndStudentBycollection" resultMap="collectionResultMap" >select * from classes c right join student s on c.cid = s.classId where c.cid=#{id}
</select>

解释:

  1. 主对象映射
    1. MyBatis 使用 resultMap 将查询结果映射到 Classes 对象上。
    2. 主键 cid 和属性 className 直接映射到对应的数据库列。
  2. 集合映射
    1. collection 标签用于映射 Classes 对象中的 students 集合。
    2. 每个 Student 对象的属性 sid, studentName, studentAge, classId 分别映射到对应的数据库列。

3)测试代码

/*** 通过collection关联查询*/
@Test
public void queryClassesAndStudentByAssociation()
{Classes classes = oneToManyMapper.queryClassesAndStudentBycollection(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student.toString());}
}

4)测试结果

2.分布查询(通过collection标签的select属性)

1)mapper

/*** 分布查询*/
Classes queryClassesAndStudentByStep(@Param("id") int id);/*** 查询id*/
List<Student> queryClassesAndStudentByStepTwo(int id);

2)mapper.xml

<!--通过分布查询-->
<resultMap id="stepResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><collection property="students"select="queryClassesAndStudentByStepTwo"column="cid"ofType="org.xiji.enty.Student"><id property="sid" column="sid"></id><result property="classId" column="classId"></result><result property="studentName" column="studentName"></result><result property="studentAge" column="studentAge"></result></collection></resultMap><select id="queryClassesAndStudentByStep" resultMap="stepResultMap" >select *from classes where cid=#{id};
</select><select id="queryClassesAndStudentByStepTwo" resultType="org.xiji.enty.Student">select * from student where classId=#{id}
</select>j

解释:

  1. 主对象映射
    1. MyBatis 使用 resultMap 将查询结果映射到 Classes 对象上。
    2. 主键 cid 和属性 className 直接映射到对应的数据库列。
  2. 分布查询
    1. collection 标签用于映射 Classes 对象中的 students 集合。
    2. 通过 select 属性指定另一个映射语句的 ID,用于执行分布查询。
    3. column 属性指定传递给分布查询的参数列名称,这里是 cid 列。
  3. 子对象映射
    1. 每个 Student 对象的属性 sid, classId, studentName, studentAge 分别映射到对应的数据库列。


 

3)测试代码

/*** 通过collection分布查询*/
@Test
public void queryClassesAndStudentByStep()
{Classes classes = oneToManyMapper.queryClassesAndStudentByStep(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student);}
}

4)测试结果

附录

1.Classes实体类

package org.xiji.enty;import java.util.ArrayList;
import java.util.List;
import org.xiji. enty.Student;/*** 班级表*/
public class Classes {private int cid;private String className;List<Student> students;public List<Student> getStudents() {return students;}public Classes(int id, String className, List<Student> students) {this.cid = id;this.className = className;this.students = students;}public Classes() {students = new ArrayList<>();}public Classes(int id, String className) {this.cid = id;this.className = className;}public int getId() {return cid;}public void setId(int id) {this.cid = id;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}public void setStudents(List<Student> students) {this.students = students;}@Overridepublic String toString() {return "Classes{" +"id=" + cid +", className='" + className + '\'' +", students=" + students +'}';}
}

2.student类

package org.xiji.enty;
import org.xiji.enty.Classes;/*** 学生表*/
public class Student {private int sid;private String studentName;private int studentAge;private int classId;private Classes classes;public Student(int id, String studentName, int studentAge, int classId, Classes classes) {this.sid = id;this.studentName = studentName;this.studentAge = studentAge;this.classId = classId;this.classes = classes;}public Student(int id, String studentName, int studentAge, int classId) {this.sid = id;this.studentName = studentName;this.studentAge = studentAge;this.classId = classId;}public Student() {}public int getId() {return sid;}public void setId(int id) {this.sid = id;}public String getStudentName() {return studentName;}public void setStudentName(String studentName) {this.studentName = studentName;}public int getStudentAge() {return studentAge;}public void setStudentAge(int studentAge) {this.studentAge = studentAge;}public int getClassId() {return classId;}public void setClassId(int classId) {this.classId = classId;}public Classes getClasses() {return classes;}public void setClasses(Classes classes) {this.classes = classes;}public void setClasses(int id,String className){this.classes = new Classes(id,className);}@Overridepublic String toString() {return "Student{" +"id=" + sid +", studentName='" + studentName + '\'' +", studentAge=" + studentAge +", classId=" + classId +", classes=" + classes +'}';}
}

3.OneToManyMapper

package org.xiji.mapper;import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.xiji.enty.Classes;
import org.xiji.enty.Student;import java.util.List;@Mapper
public interface OneToManyMapper {/*** association*/Classes queryClassesAndStudentByAssociation(@Param("id") int id);/*** 分布查询*/Classes queryClassesAndStudentByStep(@Param("id") int id);/*** 查询id*/List<Student> queryClassesAndStudentByStepTwo(int id);}

4.OneToManyMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.xiji.mapper.OneToManyMapper"><!--collection--><resultMap id="collectionResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><!--collection--><collection property="students" ofType="org.xiji.enty.Student"><id property="sid" column="sid"/><result property="studentName" column="studentName"/><result property="studentAge" column="studentAge"/><result property="classId" column="cid"/></collection></resultMap><select id="queryClassesAndStudentByAssociation" resultMap="collectionResultMap" >select * from classes c right join student s on c.cid = s.classId where c.cid=#{id}</select><!--通过分布查询--><resultMap id="stepResultMap" type="org.xiji.enty.Classes"><id property="cid" column="cid"/><result property="className" column="className"/><collection property="students"select="queryClassesAndStudentByStepTwo"column="cid"ofType="org.xiji.enty.Student"><id property="sid" column="sid"></id><result property="classId" column="classId"></result><result property="studentName" column="studentName"></result><result property="studentAge" column="studentAge"></result></collection></resultMap><select id="queryClassesAndStudentByStep" resultMap="stepResultMap" >select *from classes where cid=#{id};</select><select id="queryClassesAndStudentByStepTwo" resultType="org.xiji.enty.Student">select * from student where classId=#{id}</select></mapper>

5.OneToManyMapperTest.xml

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.xiji.enty.Classes;
import org.xiji.enty.Student;
import org.xiji.mapper.ManyToOneMapper;
import org.xiji.mapper.OneToManyMapper;import java.util.List;@SpringJUnitConfig(locations = {"classpath:springConfig.xml"})
public class OneTwoManyMapperTest {@Autowiredprivate OneToManyMapper oneToManyMapper;/*** 通过collection关联查询*/@Testpublic void queryClassesAndStudentByAssociation(){Classes classes = oneToManyMapper.queryClassesAndStudentByAssociation(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student.toString());}}/*** 通过collection分布查询*/@Testpublic void queryClassesAndStudentByStep(){Classes classes = oneToManyMapper.queryClassesAndStudentByStep(1);System.out.println(classes);List<Student> students = classes.getStudents();for (Student student : students) {System.out.println(student);}}
}

 6.sql

studentSql

/*Navicat Premium Data TransferSource Server         : mybatisSource Server Type    : MySQLSource Server Version : 80025Source Host           : localhost:3306Source Schema         : mybatisTarget Server Type    : MySQLTarget Server Version : 80025File Encoding         : 65001Date: 15/09/2024 23:50:47
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (`sid` int NOT NULL AUTO_INCREMENT COMMENT '学生id',`studentName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生姓名',`studentAge` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生年龄',`classId` int NULL DEFAULT NULL COMMENT '班级id',PRIMARY KEY (`sid`) USING BTREE,INDEX `classId`(`classId` ASC) USING BTREE,CONSTRAINT `classId` FOREIGN KEY (`classId`) REFERENCES `classes` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '张三', '18', 1);
INSERT INTO `student` VALUES (2, '李四', '20', 1);
INSERT INTO `student` VALUES (3, '小久', '21', 1);
INSERT INTO `student` VALUES (4, 'xiji', '22', 1);SET FOREIGN_KEY_CHECKS = 1;

classesSql

/*Navicat Premium Data TransferSource Server         : mybatisSource Server Type    : MySQLSource Server Version : 80025Source Host           : localhost:3306Source Schema         : mybatisTarget Server Type    : MySQLTarget Server Version : 80025File Encoding         : 65001Date: 15/09/2024 23:51:16
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for classes
-- ----------------------------
DROP TABLE IF EXISTS `classes`;
CREATE TABLE `classes`  (`cid` int NOT NULL AUTO_INCREMENT COMMENT '班级id',`className` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '班级名称',PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of classes
-- ----------------------------
INSERT INTO `classes` VALUES (1, '一班');
INSERT INTO `classes` VALUES (2, '二班');
INSERT INTO `classes` VALUES (3, '三班');
INSERT INTO `classes` VALUES (5, '五班');SET FOREIGN_KEY_CHECKS = 1;

相关文章:

MyBatis中一对多关系的两种处理方法

目录 1.多表联查&#xff08;通过collection标签的ofType属性&#xff09; 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff09;测试代码 4&#xff09;测试结果 2.分布查询(通过collection标签的select属性) 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff0…...

视频美颜SDK与直播美颜工具的实现原理与优化方案

本篇文章&#xff0c;小编将为大家详细讲解视频美颜SDK的实现原理&#xff0c;并提出优化方案。 一、视频美颜SDK的实现原理 1.图像采集与处理 2.人脸识别与关键点检测 3.美颜滤镜与特效处理 4.实时性与低延迟 二、直播美颜工具的实现原理 直播美颜工具与视频美颜SDK的…...

Linux 安装JDK8和卸载

目录 一、下载JDK8的rpm包 二、安装JDK 三、设置环境变量 Linux环境下安装JDK的方式有多种&#xff0c;可以通过rpm包、yum安装或者tar.gz压缩包。本章节会教大家通过前两者方式来安装JDK&#xff0c;压缩包的形式因为下载压缩包后上传到服务器环境下&#xff0c;将压缩包解…...

javascript 浏览器打印不同页面设置方向,横向纵向打印

// 在JavaScript中添加打印样式 const printStyle document.createElement(style); printStyle.innerHTML media print { page { size: landscape; }body { margin: 10mm; } }; document.head.appendChild(printStyle);// 触发打印 function printPage() {window.print(); }/…...

Maven 的多种打jar包方式详细介绍、区别及使用教程——附使用命令

文章目录 1. **标准 JAR 打包****打包方式****配置示例****使用方式****优点****缺点** 2. **可执行 JAR&#xff08;Executable JAR&#xff09;****打包方式****配置示例****使用方式****优点****缺点** 3. **Uber JAR&#xff08;Fat JAR / Shadow JAR&#xff09;****打包方…...

计算机毕业设计 基于协同过滤算法的个性化音乐推荐系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

Arthas 全攻略:让调试变得简单

文章目录 一、简介二、命令列表 一、简介 注意 &#xff1a; 我安装的版本是&#xff1a;Arthas V3.7.2 官网&#xff1a;https://arthas.aliyun.com/doc/ 相关错误解决方案请看GitHub&#xff1a;https://github.com/alibaba/arthas/issues Alibaba开源的Java诊断工具。 从…...

icpc江西:L. campus(dij最短路)

题目 在樱花盛开的季节&#xff0c;西湖大学吸引了大量游客&#xff0c;这让胥胥非常烦恼。于是&#xff0c;他发明了一个神奇的按钮&#xff0c;按下按钮后&#xff0c;校园里所有的游客都会以光速从最近的大门离开学校。现在&#xff0c;胥胥非常好奇&#xff0c;游客们以光…...

日志收集工具 Fluentd vs Fluent Bit 的区别

参考链接&#xff1a; FluentdFluentd BitFluentd & Fluent Bit | Fluent Bit: Official Manual Fluentd 与 Fluent Bit 两者都是生产级遥测生态系统&#xff01; 遥测数据处理可能很复杂&#xff0c;尤其是在大规模处理时。这就是创建 Fluentd 的原因。 Fluentd 不仅仅是…...

PostgreSQL技术内幕11:PostgreSQL事务原理解析-MVCC

文章目录 0.简介1.MVCC介绍2.MVCC常见的实现方式3.PG的MVCC实现3.1 可见性判断3.2 提交/取消 0.简介 本文主要介绍在事务模块中MVCC(多版本并发控制&#xff09;常见的实现方式&#xff0c;优缺点以及PG事务模块中MVCC&#xff08;多版本并发控制&#xff09;的实现。 1.MVCC…...

Java-面向对象编程(基础部分)

类和对象的区别和联系 类&#xff1a;类是封装对象的属性和行为的载体&#xff0c;在Java语言中对象的属性以成员变量的形式存在&#xff0c;而对象的方法以成员方法的形式存在。 对象&#xff1a;Java是面向对象的程序设计语言&#xff0c;对象是由类抽象出来的&#xff0c;…...

SMS over IP原理

目录 1. 短消息业务的实现方式 2. 传统 CS 短消息业务中的发送与送达报告 3. MAP/CAP 信令常见消息 4. SMS over IP 特点概述 5. SMS over IP 中的主要流程 5.1 短消息注册流程(NR 或 LTE 接入) 5.2 短消息发送(MO)流程(NR 或 LTE 接入) 5.3 短消息接收(MT)流程(NR 或…...

Linux中使用Docker容器构建Tomcat容器完整教程

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…...

【机器学习】7 ——k近邻算法

机器学习7——k近邻 输入&#xff1a;实例的特征向量 输出&#xff1a;类别 懒惰学习&#xff08;lazy learning&#xff09;的代表算法 文章目录 机器学习7——k近邻1.k近邻2.模型——距离&#xff0c;k&#xff0c;分类规则2.1距离——相似程度的反映2.2 k值分类规则 算法实…...

2024.09.09 校招 实习 内推 面经

&#x1f6f0;️ &#xff1a;neituijunsir 交* 流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招 | 佑驾创新 MINIEYE 2025校园招聘正式启动&#xff08;内推&#xff09; 校招 | 佑驾创新 MINIEYE 2025校园招聘正式启动&#xff08;内推&#xff09; 2、校招 | 长安汽…...

浅谈Linux中的环回设备

什么是环回设备 环回设备&#xff08;loop device&#xff09; 是 Linux 系统中一种特殊的虚拟设备&#xff0c;它允许你将一个普通的文件当作块设备来操作。这意味着&#xff0c;借助环回设备&#xff0c;文件可以模拟为一个磁盘或分区&#xff0c;供系统读写。这种机制非常有…...

聚焦汽车智能化与电动化,亚洲领先的汽车工业技术博览会 2025年11月与您相约 AUTO TECH 华南展

抢占市场先机︱聚焦汽车智能化与电动化&#xff0c;亚洲领先的汽车工业技术博览会 2025年11月与您相约 AUTO TECH 华南展 随着汽车智能化与电动化的迅猛发展&#xff0c;汽车电子技术、车用功率半导体技术、智能座舱技术、轻量化技术/材料、软件定义汽车、EV/HV技术、测试测量技…...

(史上最全)线程池

线程池 文章目录 线程池一&#xff0c;前言二&#xff0c;线程池三&#xff0c;参数四&#xff0c;线程池的实现原理5.线程池的使用案例(自定义线程池)6.使用Executors 创建常见的功能线程池1.固定大小线程池2.定时线程3.可缓存线程池4.单线程化线程池 一&#xff0c;前言 虽然…...

【ShuQiHere】 支持向量机(SVM)详解:从理论到实践,这一篇就够了

&#x1f4d6; 【ShuQiHere】 在现代机器学习课程中&#xff0c;支持向量机&#xff08;SVM&#xff09; 是不可或缺的一部分。它不仅在分类任务中有出色表现&#xff0c;还能灵活处理回归问题。尽管看似复杂&#xff0c;SVM 背后的思想却深刻而优雅。今天我们将全面探讨**支持…...

log4j2线程级动态日志级别

详见 参考 着重说明&#xff1a; DynamicThresholdFilter&#xff1a; 配置长这样&#xff1a;配置解释链接 <DynamicThresholdFilter key"logLevel" defaultThreshold"ERROR" onMatch"ACCEPT" onMismatch"DENY"><KeyVa…...

Unity LineRenderer不只是画线:5个实战案例教你做激光、轨迹与魔法特效

Unity LineRenderer实战进阶&#xff1a;从激光瞄准到魔法光束的5种创意实现 在Unity游戏开发中&#xff0c;LineRenderer常被简单地视为"画线工具"&#xff0c;但它的潜力远不止于此。当我们将这个组件与物理系统、着色器技术和游戏逻辑相结合时&#xff0c;它能创造…...

Pixel Dream Workshop一文详解:基于diffusers的FluxPipeline定制部署

Pixel Dream Workshop一文详解&#xff1a;基于diffusers的FluxPipeline定制部署 1. 像素幻梦创意工坊概述 Pixel Dream Workshop&#xff08;像素幻梦创意工坊&#xff09;是一款专为像素艺术创作设计的AI生成工具&#xff0c;基于最新的FLUX.1-dev扩散模型构建。与传统AI绘…...

搜索时代的命名战略:如何在亚马逊规避“品牌失语症”

在亚马逊这个由算法与关键词统治的商业世界里&#xff0c;一个名字的恰当与否&#xff0c;直接决定了品牌是“响亮宣言”还是“沉默失语”。许多名字如同《时代》或《财富》杂志&#xff0c;在传统语境中或许优雅&#xff0c;但在需要极致精准的数字货架上&#xff0c;却可能因…...

图像处理中的NCC算法:从原理到优化(附Python实现对比)

图像处理中的NCC算法&#xff1a;从原理到优化&#xff08;附Python实现对比&#xff09; 在计算机视觉领域&#xff0c;模板匹配是一项基础而重要的技术。想象一下这样的场景&#xff1a;你正在开发一个工业质检系统&#xff0c;需要在流水线上快速识别产品上的特定标识&#…...

USB批量传输中ZLP的必要性:为何512字节整数倍数据包会丢失

1. USB批量传输中的ZLP到底是什么&#xff1f; 第一次遇到USB批量传输丢数据的问题时&#xff0c;我也是一头雾水。明明发送端显示数据已经成功发送&#xff0c;接收端却死活收不到完整数据。后来排查发现&#xff0c;问题出在数据包大小刚好是512字节的整数倍时。这就是我们今…...

告别手动启动:教你写一个ROS2 Launch文件,一键运行robot_state_publisher和rviz2显示URDF

ROS2高效开发指南&#xff1a;用Launch文件一键启动机器人可视化系统 每次调试URDF模型都要重复输入一堆命令&#xff1f;手动启动robot_state_publisher、joint_state_publisher和rviz2节点不仅浪费时间&#xff0c;还容易遗漏参数。本文将带你深度掌握ROS2 Launch文件的编写…...

嵌入式Linux实战:全志T3+vsftpd实现轻量级文件传输(含WinSCP连接教程)

嵌入式Linux实战&#xff1a;全志T3vsftpd实现轻量级文件传输&#xff08;含WinSCP连接教程&#xff09; 在物联网设备开发中&#xff0c;文件传输是一个看似简单却充满挑战的环节。当你的开发板是全志T3这样的资源受限平台时&#xff0c;如何在有限的存储和内存条件下搭建一个…...

暗黑破坏神2终极单机优化:PlugY生存工具包完整指南

暗黑破坏神2终极单机优化&#xff1a;PlugY生存工具包完整指南 【免费下载链接】PlugY PlugY, The Survival Kit - Plug-in for Diablo II Lord of Destruction 项目地址: https://gitcode.com/gh_mirrors/pl/PlugY 厌倦了暗黑破坏神2单机模式的储物空间限制&#xff1f…...

当LLM学会“思考”算法逻辑:拆解EoH如何用“思想+代码”协同进化,碾压传统自动设计

当LLM成为算法设计师&#xff1a;揭秘EoH如何用“思维代码”双螺旋进化重塑自动算法设计 想象一下&#xff0c;你正在指挥一支由建筑师和施工队组成的特殊团队。建筑师负责绘制蓝图&#xff0c;施工队负责将蓝图变为现实。但与传统团队不同&#xff0c;你的建筑师能根据施工反…...

AI 创作者指南:09.AI 作为你的创作运营助理

第 9 篇 AI 作为你的创作运营助理 多模态魔法刚玩完,你现在一篇文章能变10种形态,是不是已经觉得内容像会“分身术”了?😊 来,第三部分继续!第9篇——AI 作为你的创作运营助理。 以前你自己盯排期、想矩阵、试标题,累得像管家婆。现在AI直接当你的“运营小秘书”,帮你…...