Spring Boot 整合 MongoDB 最佳实践:CRUD、分页、事务、索引全覆盖

简介: Spring Data MongoDB提供了简洁的API,让开发者能够专注于业务逻辑,快速构建高性能的应用。通过合理使用MongoDB的特性,可以充分发挥其文档数据库的优势。

大家好,我是小悟。

一、需求描述

业务场景:开发一个博客文章管理系统

  • 实现文章的基本CRUD操作
  • 支持文章的评论功能
  • 支持根据标题和内容模糊搜索
  • 记录文章的创建和更新时间
  • 支持文章标签管理

技术需求

  • 使用Spring Boot 2.x
  • 使用MongoDB存储数据
  • 提供RESTful API接口
  • 使用MongoTemplate和MongoRepository两种方式操作数据

二、详细步骤

1. 环境准备

安装MongoDB

# MacOS
brew install mongodb-community
brew services start mongodb-community
# 验证安装
mongo --version

2. 创建Spring Boot项目

pom.xml依赖配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>mongodb-demo</artifactId>
    <version>1.0.0</version>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring Data MongoDB -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. 配置文件

application.yml

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      database: blogdb
      # 如果需要认证
      # username: admin
      # password: admin123
      # authentication-database: admin
server:
  port: 8080
logging:
  level:
    org.springframework.data.mongodb: DEBUG

4. 实体类设计

Article.java

package com.example.mongodb.entity;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "articles")  // 指定集合名称
public class Article {
    
    @Id
    private String id;  // MongoDB默认使用ObjectId,这里用String接收
    
    @Indexed(unique = true)  // 创建唯一索引
    private String title;
    
    @Field("content")  // 指定字段名
    private String content;
    
    private String author;
    
    private List<String> tags;
    
    private Integer viewCount;
    
    private List<Comment> comments;
    
    @Field("createTime")
    private LocalDateTime createTime;
    
    @Field("updateTime")
    private LocalDateTime updateTime;
    
    private Boolean published;
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Comment {
        private String username;
        private String content;
        private LocalDateTime commentTime;
        private Integer likes;
    }
}

5. Repository层

使用MongoRepository方式

package com.example.mongodb.repository;
import com.example.mongodb.entity.Article;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ArticleRepository extends MongoRepository<Article, String> {
    
    // 根据作者查询
    List<Article> findByAuthor(String author);
    
    // 根据标签查询
    List<Article> findByTagsIn(List<String> tags);
    
    // 根据标题模糊查询
    List<Article> findByTitleLike(String title);
    
    // 根据发布时间范围查询
    List<Article> findByCreateTimeBetween(LocalDateTime start, LocalDateTime end);
    
    // 使用@Query注解自定义查询
    @Query("{'title': {$regex: ?0}, 'published': true}")
    List<Article> findPublishedArticlesByTitle(String title);
    
    // 复杂的嵌套查询
    @Query("{'comments.username': ?0}")
    List<Article> findByCommentUsername(String username);
}

使用MongoTemplate方式

package com.example.mongodb.repository;
import com.example.mongodb.entity.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class ArticleTemplateRepository {
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    // 条件查询
    public List<Article> findByCondition(String keyword, String author) {
        Query query = new Query();
        
        // 添加查询条件
        if (keyword != null && !keyword.isEmpty()) {
            query.addCriteria(Criteria.where("title").regex(keyword)
                    .orOperator(Criteria.where("content").regex(keyword)));
        }
        
        if (author != null && !author.isEmpty()) {
            query.addCriteria(Criteria.where("author").is(author));
        }
        
        // 只查询已发布的文章
        query.addCriteria(Criteria.where("published").is(true));
        
        // 排序
        query.with(Sort.by(Sort.Direction.DESC, "createTime"));
        
        return mongoTemplate.find(query, Article.class);
    }
    
    // 更新评论点赞数
    public void updateCommentLikes(String articleId, String commentUsername, int increment) {
        Query query = new Query(Criteria.where("id").is(articleId)
                .and("comments.username").is(commentUsername));
        
        Update update = new Update().inc("comments.$.likes", increment);
        
        mongoTemplate.updateFirst(query, update, Article.class);
    }
    
    // 增加文章浏览量
    public void incrementViewCount(String articleId) {
        Query query = new Query(Criteria.where("id").is(articleId));
        Update update = new Update().inc("viewCount", 1);
        mongoTemplate.updateFirst(query, update, Article.class);
    }
    
    // 批量更新
    public void updateArticlesStatusByAuthor(String author, Boolean status) {
        Query query = new Query(Criteria.where("author").is(author));
        Update update = new Update().set("published", status);
        mongoTemplate.updateMulti(query, update, Article.class);
    }
}

6. Service层

package com.example.mongodb.service;
import com.example.mongodb.entity.Article;
import com.example.mongodb.repository.ArticleRepository;
import com.example.mongodb.repository.ArticleTemplateRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Service
public class ArticleService {
    
    @Autowired
    private ArticleRepository articleRepository;
    
    @Autowired
    private ArticleTemplateRepository articleTemplateRepository;
    
    // 创建文章
    public Article createArticle(Article article) {
        article.setId(null); // 确保是新文章
        article.setCreateTime(LocalDateTime.now());
        article.setUpdateTime(LocalDateTime.now());
        article.setViewCount(0);
        return articleRepository.save(article);
    }
    
    // 更新文章
    public Article updateArticle(String id, Article article) {
        return articleRepository.findById(id)
                .map(existingArticle -> {
                    article.setId(id);
                    article.setCreateTime(existingArticle.getCreateTime());
                    article.setUpdateTime(LocalDateTime.now());
                    return articleRepository.save(article);
                })
                .orElseThrow(() -> new RuntimeException("文章不存在"));
    }
    
    // 删除文章
    public void deleteArticle(String id) {
        articleRepository.deleteById(id);
    }
    
    // 查询单篇文章
    public Article getArticle(String id) {
        return articleRepository.findById(id)
                .map(article -> {
                    // 阅读量+1
                    articleTemplateRepository.incrementViewCount(id);
                    article.setViewCount(article.getViewCount() + 1);
                    return article;
                })
                .orElseThrow(() -> new RuntimeException("文章不存在"));
    }
    
    // 查询所有文章
    public List<Article> getAllArticles() {
        return articleRepository.findAll();
    }
    
    // 根据作者查询
    public List<Article> getArticlesByAuthor(String author) {
        return articleRepository.findByAuthor(author);
    }
    
    // 条件搜索
    public List<Article> searchArticles(String keyword, String author) {
        return articleTemplateRepository.findByCondition(keyword, author);
    }
    
    // 添加评论
    public Article addComment(String articleId, Article.Comment comment) {
        return articleRepository.findById(articleId)
                .map(article -> {
                    comment.setCommentTime(LocalDateTime.now());
                    comment.setLikes(0);
                    article.getComments().add(comment);
                    article.setUpdateTime(LocalDateTime.now());
                    return articleRepository.save(article);
                })
                .orElseThrow(() -> new RuntimeException("文章不存在"));
    }
    
    // 点赞评论
    public void likeComment(String articleId, String username) {
        articleTemplateRepository.updateCommentLikes(articleId, username, 1);
    }
}

7. Controller层

package com.example.mongodb.controller;
import com.example.mongodb.entity.Article;
import com.example.mongodb.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/articles")
public class ArticleController {
    
    @Autowired
    private ArticleService articleService;
    
    @PostMapping
    public ResponseEntity<Article> createArticle(@RequestBody Article article) {
        Article created = articleService.createArticle(article);
        return new ResponseEntity<>(created, HttpStatus.CREATED);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<Article> updateArticle(@PathVariable String id, 
                                                  @RequestBody Article article) {
        Article updated = articleService.updateArticle(id, article);
        return ResponseEntity.ok(updated);
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteArticle(@PathVariable String id) {
        articleService.deleteArticle(id);
        return ResponseEntity.noContent().build();
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<Article> getArticle(@PathVariable String id) {
        Article article = articleService.getArticle(id);
        return ResponseEntity.ok(article);
    }
    
    @GetMapping
    public ResponseEntity<List<Article>> getAllArticles() {
        List<Article> articles = articleService.getAllArticles();
        return ResponseEntity.ok(articles);
    }
    
    @GetMapping("/search")
    public ResponseEntity<List<Article>> searchArticles(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String author) {
        List<Article> articles = articleService.searchArticles(keyword, author);
        return ResponseEntity.ok(articles);
    }
    
    @PostMapping("/{id}/comments")
    public ResponseEntity<Article> addComment(
            @PathVariable String id,
            @RequestBody Article.Comment comment) {
        Article article = articleService.addComment(id, comment);
        return ResponseEntity.ok(article);
    }
    
    @PostMapping("/{id}/comments/{username}/like")
    public ResponseEntity<Void> likeComment(
            @PathVariable String id,
            @PathVariable String username) {
        articleService.likeComment(id, username);
        return ResponseEntity.ok().build();
    }
}

8. 启动类

package com.example.mongodb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@SpringBootApplication
@EnableMongoRepositories  // 启用MongoDB仓库
@EnableMongoAuditing      // 启用MongoDB审计功能
public class MongodbApplication {
    public static void main(String[] args) {
        SpringApplication.run(MongodbApplication.class, args);
    }
}

9. 测试数据初始化

package com.example.mongodb.config;
import com.example.mongodb.entity.Article;
import com.example.mongodb.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Arrays;
@Component
public class DataInitializer implements CommandLineRunner {
    
    @Autowired
    private ArticleRepository articleRepository;
    
    @Override
    public void run(String... args) throws Exception {
        // 清空数据
        articleRepository.deleteAll();
        
        // 创建测试文章
        Article article1 = Article.builder()
                .title("Spring Boot 入门教程")
                .content("本文将介绍Spring Boot的基本使用方法...")
                .author("张三")
                .tags(Arrays.asList("Java", "Spring Boot", "教程"))
                .viewCount(0)
                .published(true)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .comments(Arrays.asList(
                        Article.Comment.builder()
                                .username("李四")
                                .content("写的很好,学习了!")
                                .commentTime(LocalDateTime.now())
                                .likes(5)
                                .build()
                ))
                .build();
        
        Article article2 = Article.builder()
                .title("MongoDB 实战技巧")
                .content("分享MongoDB在实际项目中的应用经验...")
                .author("王五")
                .tags(Arrays.asList("数据库", "MongoDB", "实战"))
                .viewCount(0)
                .published(true)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .comments(Arrays.asList())
                .build();
        
        articleRepository.saveAll(Arrays.asList(article1, article2));
        
        System.out.println("测试数据初始化完成!");
    }
}

三、测试接口

使用curl测试API

# 创建文章
curl -X POST http://localhost:8080/api/articles \
  -H "Content-Type: application/json" \
  -d '{
    "title": "MongoDB高级特性",
    "content": "本文将介绍MongoDB的高级特性...",
    "author": "赵六",
    "tags": ["MongoDB", "数据库", "高级"],
    "published": true
  }'
# 查询所有文章
curl http://localhost:8080/api/articles
# 搜索文章
curl "http://localhost:8080/api/articles/search?keyword=Spring&author=张三"
# 添加评论
curl -X POST http://localhost:8080/api/articles/{id}/comments \
  -H "Content-Type: application/json" \
  -d '{
    "username": "读者A",
    "content": "非常实用的教程!"
  }'
# 点赞评论
curl -X POST http://localhost:8080/api/articles/{id}/comments/读者A/like

四、详细总结

1. MongoDB与关系型数据库的对比

特性 MongoDB MySQL
数据结构 文档型(BSON/JSON) 表格(行/列)
关联查询 内嵌文档或DBRef JOIN操作
Schema 动态schema 固定schema
扩展性 原生支持水平扩展 主从复制/分库分表
事务支持 4.0后支持多文档事务 完整ACID支持

2. Spring Data MongoDB的核心注解

注解 作用
@Document 映射MongoDB的集合
@Id 标识文档ID字段
@Field 指定字段名
@Indexed 声明索引
@CompoundIndex 复合索引
@DBRef 引用其他集合(谨慎使用)
@Transactional 支持事务操作

3. 操作方式对比

MongoRepository的优点:

  • 代码简洁,继承接口即可获得基础CRUD
  • 支持方法名解析查询
  • 与Spring Data JPA使用方式相似

MongoTemplate的优点:

  • 更灵活的查询条件构造
  • 支持批量操作和聚合查询
  • 可以执行原生MongoDB命令

4. 最佳实践建议

1. 索引设计

  • 为常用查询字段创建索引
  • 复合索引要注意字段顺序
  • 使用@Indexed注解或mongoTemplate创建索引

2. 性能优化

// 分页查询示例
Pageable pageable = PageRequest.of(0, 10, Sort.by("createTime").descending());
Page<Article> page = articleRepository.findAll(pageable);
// 只返回需要的字段
Query query = new Query();
query.fields().include("title").include("author");

3. 数据一致性

@Transactional
public void updateWithTransaction(String articleId, Comment comment) {
    // 确保两个操作原子性
    addComment(articleId, comment);
    updateArticleStats(articleId);
}

4. 异常处理

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(DuplicateKeyException.class)
    public ResponseEntity<String> handleDuplicateKey() {
        return ResponseEntity.status(HttpStatus.CONFLICT)
                .body("文章标题已存在");
    }
}

5. 常见问题解决

1. 连接认证问题

spring:
  data:
    mongodb:
      uri: mongodb://username:password@localhost:27017/dbname?authSource=admin

2. 大数据量处理

// 使用流式处理
@Autowired
private MongoTemplate mongoTemplate;
public void processLargeData() {
    Query query = new Query();
    query.cursorBatchSize(1000); // 设置批处理大小
    
    mongoTemplate.stream(query, Article.class)
        .forEach(article -> {
            // 处理每条记录
        });
}

3. 审计功能

@EntityListeners(AuditingEntityListener.class)
public class Article {
    @CreatedDate
    private LocalDateTime createTime;
    
    @LastModifiedDate
    private LocalDateTime updateTime;
}

6. 项目结构建议

src/main/java/com/example/mongodb/
├── config/           # 配置类
├── entity/           # 实体类
├── repository/       # 数据访问层
├── service/          # 业务逻辑层
├── controller/       # REST控制器
├── dto/              # 数据传输对象
├── exception/        # 异常处理
└── util/             # 工具类

五、总结

通过本实战项目,我们完整地实现了Spring Boot与MongoDB的整合,涵盖了:

  1. 基础配置:Maven依赖、YAML配置
  2. 数据建模:文档设计、嵌套文档使用
  3. 数据访问:Repository和Template两种方式
  4. 业务实现:CRUD操作、复杂查询、评论功能
  5. 性能优化:索引、分页、批量处理
  6. 最佳实践:事务、审计、异常处理

MongoDB作为NoSQL数据库的代表,特别适合以下场景:

  • 数据结构不固定,需要频繁变更
  • 需要快速迭代开发
  • 读写并发高,需要水平扩展
  • 存储复杂嵌套结构的JSON数据

Spring Data MongoDB提供了简洁的API,让开发者能够专注于业务逻辑,快速构建高性能的应用。通过合理使用MongoDB的特性,可以充分发挥其文档数据库的优势。

SpringBoot整合MongoDB,性能提升,优化实践.png

谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。

您的一键三连,是我更新的最大动力,谢谢

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

相关文章
|
21天前
|
存储 NoSQL Java
别再用定时任务扫库了!SpringBoot集成Redis实现订单超时管理
你开了一家网红奶茶店,顾客下单后30分钟不付款,订单就自动取消。你总不能雇个店员盯着每个订单看30分钟吧?Redis的过期键和发布订阅功能,就是那个不知疲倦的“自动取消专员”!
251 3
|
2天前
|
存储 人工智能 安全
小白友好 OpenClaw 2.7.1 安装与使用教程
小白友好OpenClaw 2.7.1 Windows 11一键安装教程:无需编程基础,内置完整环境,3–5分钟完成部署。支持文件整理、浏览器自动化、办公流程等本地AI任务,数据不出设备,隐私安全有保障。含常见问题解决方案。(239字)
|
17天前
|
数据采集 缓存 运维
IP查询工具如何评估IP负载?云上资源分配的实战方法
我们曾因P99延迟骤升盲目扩容无效,最终靠IP分桶定位到某云厂商ASN段的爬虫流量。IP查询工具不测性能,而是为请求打标签(ASN/代理类型/风险分等),结合监控数据精准识别“谁拖垮了系统”。分四类桶、设三条件、按优先级调度(分流>限流>扩容>封禁),离线缓存+二次验证,避免误伤。
|
1月前
|
人工智能 弹性计算 自然语言处理
阿里云轻量应用服务器部署OpenClaw应用镜像,以及OpenClaw集成QQ图文教程
本文介绍了购买阿里云轻量应用服务器并部署OpenClaw应用镜像的步骤,包括相关计费说明、购买流程、配置细节及常见问题。还阐述了如何将OpenClaw集成到QQ机器人中,实现自然语言交互,涵盖创建QQ机器人及集成步骤。通过本文,用户能够掌握从本地部署到QQ集成的完整路径,实现定制化AI助理在QQ场景下的高效应用。
|
24天前
|
人工智能 安全 机器人
阿里云JVS Claw全面开放:无需邀请码云端”养龙虾“,不需要安装体验OpenClaw,纯免费!
阿里云JVS Claw(“AI龙虾”)是基于OpenClaw打造的开箱即用AI智能体,JVS官网:https://t.aliyun.com/U/IJbaxg 支持云端/本地双模部署,无需邀请码、纯免费体验。它能真正动手执行任务——处理文档、分析数据、抓取网页、运行代码,并通过技能库(ClawHub)持续进化。三端互通,5分钟上手,让普通人也能拥有专属数字员工。
445 6
|
1月前
|
分布式计算 MaxCompute iOS开发
TorchEasyRec 在 macOS 上的功能限制总结
本文总结tzrec在macOS上的功能限制:核心依赖(如torchrec、fbgemm-gpu、graphlearn等)无法安装;分布式训练、原生数据管线、Embedding模块、Triton/CUDA算子、TDM树模型等功能完全不可用;优化器与模型导出部分失效;单元测试大多因强依赖而失败。
161 15
|
8天前
|
数据采集 自动驾驶 算法
8类道路交通车辆目标检测数据集(2600张)|YOLO训练数据集 智慧交通 自动驾驶 车流统计 车辆识别
本数据集含2600张真实道路图像,精细标注8类车辆(公交、重型/中型/牵引卡车、皮卡、轿车、两轮车、面包车),YOLO格式,覆盖城市/城郊多场景,支持智慧交通、自动驾驶、车流统计等任务,开箱即用。
130 10
|
1月前
|
应用服务中间件
手慢无!阿里云轻量服务器2026最新秒杀价:2核4G配置199元/年,200M带宽不限流
阿里云2026轻量服务器秒杀开启!轻量应用服务器官方页面:https://t.aliyun.com/U/PEdlFP 新用户专享:2核2G低至38元/年(9.9元/月限时抢),2核4G仅199元/年,4核8G/16G分别1159元、1599元/年。全系配200M峰值带宽+不限流量,性价比远超友商。手慢无!
|
23天前
|
人工智能 运维 监控
OpenClaw爆火背后,企业级智能体为何更需要“私有化部署替代方案”?
OpenClaw(“小龙虾”)引爆AI智能体热潮,但企业落地面临安全、规模化与成本三大困局。OpenOcta应运而生——专为企业打造的私有化智能体平台,具备默认安全、集中管控、成本可控及深度集成能力,已覆盖金融、政务、制造等十余行业,助力企业安全高效迈入智能体时代。(239字)
|
1月前
|
人工智能 数据可视化 API
零基础零门槛!OpenClaw 阿里云无影云电脑一键部署、iMessage对接与千问Qwen3.6-Plus配置教程
2026年,OpenClaw(原Clawdbot)作为轻量化、高扩展的AI智能体框架,凭借极简部署、多平台兼容与强大的工具调用能力,成为个人与团队搭建专属AI助理的首选方案。对于零基础用户,**阿里云无影云电脑**提供了官方认证的OpenClaw专属镜像,预装Node.js 22、Git、Homebrew等全部运行依赖,无需复杂环境配置,即可实现“分钟级部署、7×24小时稳定运行”。同时,通过官方imessage-connector插件可无缝对接苹果iMessage平台,搭配**阿里云千问Qwen3.6-Plus**大模型的高性能API,可实现长文本理解、复杂推理、代码生成、多轮对话等核心能力
307 6