【JAVA】SpringBoot + mongodb 分页、排序、动态多条件查询及事务处理
【JAVA】SpringBoot + mongodb 分页、排序、动态多条件查询及事务处理
1.引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mongodb ↓ --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><!-- mongodb ↑ -->
2.配置application.yml
spring:data:# mongodb多数据源配置mongodb:host: 192.168.36.238port: 27017username: yapipassword: Qsxdcfr2313!database: yapi# 验证数据库authentication-database: admin# 第二个数据库low-code:uri: mongodb://yapi:Qsxdcfr2313!@192.168.36.238:27017/low-code?authSource=admin# 第三个数据库event:uri: mongodb://yapi:Qsxdcfr2313!@192.168.36.238:27017/event?authSource=admin
3.MongoDB多数据源配置
创建MongoConfig类
package com.xhs.config;import com.mongodb.client.MongoClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;import javax.annotation.Resource;/*** @desc: MongoDB多数据源配置* @projectName: spring-boot-demo* @author: xhs* @date: 2023-11-23 16:06:22* @version: JDK 1.8*/@Configuration
public class MongoConfig {@Resourceprivate MongoClient mongoClient;@Resourceprivate MongoProperties mongoProperties;/*** 默认的数据库** @return MongoTemplate*/@Beanpublic MongoTemplate mongoTemplate() {return new MongoTemplate(mongoClient, mongoProperties.getDatabase());}/*** 第二个数据源** @param adminUri uri* @return MongoTemplate*/@Beanpublic MongoTemplate mongoTemplateLowCode(@Value("${spring.data.mongodb.low-code.uri}") String adminUri) {return new MongoTemplate(new SimpleMongoClientDatabaseFactory(adminUri));}/*** 第三个数据源** @param adminUri uri* @return MongoTemplate*/@Beanpublic MongoTemplate mongoTemplateEvent(@Value("${spring.data.mongodb.event.uri}") String adminUri) {return new MongoTemplate(new SimpleMongoClientDatabaseFactory(adminUri));}
}
4.创建实体类
创建三个库的实体类
第一库的实体类
package com.xhs.entity.mongo;import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;/*** @desc: yapi库的user集合* @projectName: spring-boot-demo* @author: xhs* @date: 2023-11-23 023 16:14* @version: JDK 1.8*/
@Data
@Document(collection = "user")
public class User {@Idprivate String id;/*** 用户名*/private String username;/*** 角色*/private String role;
}
第二个库的实体类
package com.xhs.entity.mongo;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;/*** @desc: low-code库的low_code_url集合* @projectName: spring-boot-demo* @author: xhs* @date: 2023-11-23 023 16:10* @version: JDK 1.8*/
@Data
@Document(collection = "low_code_url")
public class LowCodeUrl {@Idprivate String id;/*** 系统类型*/private String systemName;/*** 对象名称*/private String objectName;/*** 接口地址*/private String interfaceUrl;/*** 接口类型*/private String interfaceType;/*** 创建时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;/*** 更新时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date updateTime;
}
第三个库的实体类
package com.xhs.entity.mongo;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;/*** @desc: event库的event集合* @projectName: spring-boot-demo* @author: xhs* @date: 2023-11-23 023 16:17* @version: JDK 1.8*/
@Data
@Document(collection = "event")
public class Event {@Idprivate String id;/*** 事件名称*/private String eventName;/*** 事件类型*/private String eventType;/*** 触发方式*/private String triggerMode;/*** 创建时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;/*** 更新时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date updateTime;
}
5.创建Controller层
package com.xhs.controller;import com.xhs.dto.request.AddEventParams;
import com.xhs.dto.request.AddLowCodeUrlParams;
import com.xhs.dto.request.FindLowCodeUrlParams;
import com.xhs.dto.request.PageEventParams;
import com.xhs.message.ReturnResult;
import com.xhs.service.MongoService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/*** @desc:* @projectName: spring-boot-demo* @author: xhs* @date: 2023-11-23 023 16:19* @version: JDK 1.8*/
@RestController
@RequestMapping("/mongo")
public class MongoController {@Resourceprivate MongoService mongoService;/*** 查询所有用户** @return ReturnResult<Object>*/@GetMapping("/getUser")public ReturnResult<Object> getUser() {return mongoService.getUser();}/*** 条件查询 LowCodeUrl** @param findLowCodeUrlParams 查询条件* @return ReturnResult<Object>*/@PostMapping("/getLowCodeUrl")public ReturnResult<Object> getLowCodeUrl(@RequestBody FindLowCodeUrlParams findLowCodeUrlParams) {return mongoService.getLowCodeUrl(findLowCodeUrlParams);}/*** 新增 LowCodeUrl 数据** @param lowCodeUrlParams LowCodeUrl 数据* @return ReturnResult<Object>*/@PostMapping("/addLowCodeUrl")public ReturnResult<Object> addLowCodeUrl(@Validated @RequestBody AddLowCodeUrlParams lowCodeUrlParams) {return mongoService.addLowCodeUrl(lowCodeUrlParams);}/*** 新增 event 数据** @param eventParams LowCodeUrl 数据* @return ReturnResult<Object>*/@PostMapping("/addEvent")public ReturnResult<Object> addEvent(@Validated @RequestBody AddEventParams eventParams) {return mongoService.addEvent(eventParams);}/*** 分页查询 event 数据** @param eventParams 查询条件* @return ReturnResult<Object>*/@PostMapping("/pageEvent")public ReturnResult<Object> pageEvent(@Validated @RequestBody PageEventParams eventParams) {return mongoService.pageEvent(eventParams);}
}
6.创建Service层
package com.xhs.service;import com.xhs.dto.request.AddEventParams;
import com.xhs.dto.request.AddLowCodeUrlParams;
import com.xhs.dto.request.FindLowCodeUrlParams;
import com.xhs.dto.request.PageEventParams;
import com.xhs.message.ReturnResult;/*** @desc:* @projectName: spring-boot-demo* @author: xhs* @date: 2023-11-23 023 16:20* @version: JDK 1.8*/
public interface MongoService {/*** 查询所有用户** @return ReturnResult<Object>*/ReturnResult<Object> getUser();/*** 条件查询 LowCodeUrl** @param findLowCodeUrlParams 查询条件* @return ReturnResult<Object>*/ReturnResult<Object> getLowCodeUrl(FindLowCodeUrlParams findLowCodeUrlParams);/*** 新增 LowCodeUrl 数据** @param lowCodeUrlParams LowCodeUrl 数据* @return ReturnResult<Object>*/ReturnResult<Object> addLowCodeUrl(AddLowCodeUrlParams lowCodeUrlParams);/*** 新增 event 数据** @param eventParams LowCodeUrl 数据* @return ReturnResult<Object>*/ReturnResult<Object> addEvent(AddEventParams eventParams);/*** 分页查询 event 数据** @param eventParams 查询条件* @return ReturnResult<Object>*/ReturnResult<Object> pageEvent(PageEventParams eventParams);
}
7.创建ServiceImpl层
package com.xhs.service.impl;import com.xhs.dto.request.AddEventParams;
import com.xhs.dto.request.AddLowCodeUrlParams;
import com.xhs.dto.request.FindLowCodeUrlParams;
import com.xhs.dto.request.PageEventParams;
import com.xhs.dto.response.PageResult;
import com.xhs.entity.mongo.Event;
import com.xhs.entity.mongo.LowCodeUrl;
import com.xhs.entity.mongo.User;
import com.xhs.message.Result;
import com.xhs.message.ReturnResult;
import com.xhs.service.MongoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;import javax.annotation.Resource;
import java.util.Date;
import java.util.List;/*** @desc:* @projectName: spring-boot-demo* @author: xhs* @date: 2023-11-23 023 16:20* @version: JDK 1.8*/
@Slf4j
@Service
public class MongoServiceImpl implements MongoService {@Resource@Qualifier("mongoTemplate")private MongoTemplate mongoTemplate;@Resource@Qualifier("mongoTemplateLowCode")private MongoTemplate mongoTemplateLowCode;@Resource@Qualifier("mongoTemplateEvent")private MongoTemplate mongoTemplateEvent;/*** 查询所有用户** @return ReturnResult<Object>*/@Overridepublic ReturnResult<Object> getUser() {List<User> users = mongoTemplate.find(new Query(), User.class);return ReturnResult.build(Result.QUERY_SUCCESS).setData(users);}/*** 条件查询 LowCodeUrl** @param findLowCodeUrlParams 查询条件* @return ReturnResult<Object>*/@Overridepublic ReturnResult<Object> getLowCodeUrl(FindLowCodeUrlParams findLowCodeUrlParams) {Query query = new Query();if (StringUtils.hasLength(findLowCodeUrlParams.getSystemName())) {// regex 模糊查询query.addCriteria(Criteria.where("systemName").regex(findLowCodeUrlParams.getSystemName()));}if (StringUtils.hasLength(findLowCodeUrlParams.getObjectName())) {// regex 模糊查询query.addCriteria(Criteria.where("objectName").regex(findLowCodeUrlParams.getObjectName()));}if (StringUtils.hasLength(findLowCodeUrlParams.getInterfaceType())) {query.addCriteria(Criteria.where("interfaceType").is(findLowCodeUrlParams.getInterfaceType()));}List<LowCodeUrl> lowCodeUrlList = mongoTemplateLowCode.find(query, LowCodeUrl.class);return ReturnResult.build(Result.QUERY_SUCCESS).setData(lowCodeUrlList);}/*** 新增 LowCodeUrl 数据** @param lowCodeUrlParams LowCodeUrl 数据* @return ReturnResult<Object>*/@Override@Transactional(rollbackFor = Exception.class)public ReturnResult<Object> addLowCodeUrl(AddLowCodeUrlParams lowCodeUrlParams) {Date date = new Date();LowCodeUrl codeUrl = new LowCodeUrl();codeUrl.setSystemName(lowCodeUrlParams.getSystemName());codeUrl.setObjectName(lowCodeUrlParams.getObjectName());codeUrl.setInterfaceUrl(lowCodeUrlParams.getInterfaceUrl());codeUrl.setInterfaceType(lowCodeUrlParams.getInterfaceType());codeUrl.setCreateTime(date);codeUrl.setUpdateTime(date);LowCodeUrl insert = mongoTemplateLowCode.insert(codeUrl);return ReturnResult.build(Result.ADD_SUCCESS).setData(insert.getId());}/*** 新增 event 数据** @param eventParams LowCodeUrl 数据* @return ReturnResult<Object>*/@Overridepublic ReturnResult<Object> addEvent(AddEventParams eventParams) {Date date = new Date();Event event = new Event();event.setEventName(eventParams.getEventName());event.setEventType(eventParams.getEventType());event.setTriggerMode(eventParams.getTriggerMode());event.setCreateTime(date);event.setUpdateTime(date);Event insert = mongoTemplateEvent.insert(event);return ReturnResult.build(Result.ADD_SUCCESS).setData(insert.getId());}/*** 分页查询 event 数据** @param eventParams 查询条件* @return ReturnResult<Object>*/@Overridepublic ReturnResult<Object> pageEvent(PageEventParams eventParams) {// 排序字段Sort sort = Sort.by(Sort.Direction.DESC, "createTime");// 分页,PageNumber()-1是因为第一页的下标为0 ,入参PageNumber最小值为1Pageable pageRequest = PageRequest.of(eventParams.getPageNumber()-1, eventParams.getPageSize(), sort);// 查询条件Query query = new Query();if (StringUtils.hasLength(eventParams.getEventName())) {// regex 模糊查询query.addCriteria(Criteria.where("eventName").regex(eventParams.getEventName()));}if (StringUtils.hasLength(eventParams.getEventType())) {// regex 模糊查询query.addCriteria(Criteria.where("eventType").regex(eventParams.getEventType()));}if (StringUtils.hasLength(eventParams.getTriggerMode())) {// regex 模糊查询query.addCriteria(Criteria.where("triggerMode").regex(eventParams.getTriggerMode()));}query.with(pageRequest);// 查询总数long count = mongoTemplateEvent.count(query, Event.class);// 查询数据List<Event> events = mongoTemplateEvent.find(query, Event.class);// 分页结果PageResult<List<Event>> result = new PageResult<>();result.setPageNumber(eventParams.getPageNumber());result.setPageSize(eventParams.getPageSize());result.setTotalRow(count);result.setRecords(events);return ReturnResult.build(Result.QUERY_SUCCESS).setData(result);}
}
8.源码地址
https://gitee.com/xhs101/spring-boot-demo
9.查询效果:


相关文章:
【JAVA】SpringBoot + mongodb 分页、排序、动态多条件查询及事务处理
【JAVA】SpringBoot mongodb 分页、排序、动态多条件查询及事务处理 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mongodb ↓ -->&…...
nrm安装及使用
一、介绍 nrm 是一个 Node.js 的 registry 管理工具,它允许你快速地在不同的 npm registry 之间进行切换。通过使用 nrm,你可以方便地将 npm 的 registry 切换为淘宝镜像、npm 官方镜像或者其他定制的镜像,以加快包的下载速度。nrm仓库请点击…...
docker报错standard init linux.go:228 exec user process caused: exec format error
1、报错 使用Dockerfile自己做的服务镜像,docker run时启动失败,报错如下: standard init linux.go:228 exec user process caused: exec format error2、原因一 当前服务器的CPU架构和构建镜像时的CPU架构不兼容。比如做镜像是在arm机器下…...
Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
Docker 是一种容器化技术,它将一个应用程序及其所有依赖项打包在一起,形成一个独立的、可移植的容器。这个容器可以在任何支持 Docker 的操作系统上运行,而且具有很好的可移植性和可扩展性。以下是 Docker 的基本概念和优势: 镜像…...
libmosquitto库的一个bug,任务消息id(mid)分配后不起作用
代码如图所示: 当订阅了所有主题后,每个主题的mid是他们的下标索引加100的数字,可是实际打印出来的值是: mid依然是1,2,这个参数在这里失效了,不知道是bug还是mqtt的什么机制?...
亚马逊云科技re:Invent大会:云计算与生成式AI共筑科技新局面,携手构建未来
随着科技的飞速发展,云计算和生成式 AI 已经成为了推动科技进步的重要力量。这两者相互结合,正在为我们创造一个全新的科技局面。 亚马逊云科技的re:Invent大会再次证明了云计算和生成式AI的强大结合正在塑造科技的新未来。这次大会聚焦了云计算的前沿技…...
Docker 部署 Nacos(单机),利用 MySQL 数据库存储配置信息
前面的话 默认你已经懂 Docker、docker-compose Nacos版本:v2.2.3 MySQL 版本:8.2.0 一、下载 打开 Nacos 官网 官网地址:官网 点击手册 左侧 Nacos Docker 克隆项目到本地 # 克隆项目,如果提示连接不到 github 请自行解决 …...
【LeeCode】35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 你可以假设数组中无重复元素。 解: class Solution {public int searchInsert(int[] nums, int target) {int …...
18.天气小案例
1►新增带Layout组件的页面 直接在views文件夹下面新增weather.vue。然后随便写一个123,现在先让我们页面能跳过去先。 让页面能跳过去,有好几种方法: 1、在菜单管理自己添加一个菜单,然后把菜单分配给某个角色,再把…...
医保线上购药系统:代码驱动的医疗创新
医保线上购药系统,这是一个融合技术和医疗的创新典范。本文将通过简单的技术代码示例,为您揭示这一系统是如何通过技术驱动医疗创新,为用户提供更智能、便捷的健康管理体验的。 1. 前端界面开发 使用React框架,我们可以轻松构建…...
VMware OpenSLP漏洞解决方案
PS:早期为客户做VMware检测的方法,大家如有遇到可参考 OpenSLP堆溢出漏洞攻击大量ESXI服务器,该漏洞编号为CVE-2021-21974,由 OpenSLP 服务中的堆溢出问题引起 大于以下版本则不受影响 ESXi versions 7.x prior to ESXi7…...
UEditor编辑器实现上传图片自动加水印功能PHP源码
UEditor编辑器是百度旗下的免费开源富文本编辑器,使用很方便,但是也有缺点,比如,上传图片不能自动添加水印,下边我们就来说说如何在UEditor编辑器中自动实现上传图片添加水印功能,操作很简单。 首先找到UEditor/PHP目录下的Uploader.class.php的文件,打开该文件,找到以…...
【从浅识到熟知Linux】基本指定之find、grep、head和tail
🎈归属专栏:从浅学到熟知Linux 🚗个人主页:Jammingpro 🐟每日一句:一篇又一篇,学写越上头。 文章前言:本文介绍find、grep、head和tail指令用法并给出示例和截图。 文章目录 find基本…...
【云备份】文件操作实用工具类设计
文章目录 为什么要单独设计文件工具类?整体实现Filesize ——文件大小stat接口 LastMTime ——最后一次修改时间LastATime —— 最后一次访问时间FileName —— 文件名称GetPostLen ——获取文件指定位置 指定长度的数据GetContnet —— 读取文件数据SetContent ——…...
LeetCode Hot100 199.二叉树的右视图
题目: 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 方法(灵神):先递归右子树,再递归左子树,在递归的同…...
Nacos身份绕过漏洞复现(QVD-2023-6271)
Nacos身份绕过漏洞复现(QVD-2023-6271) 环境配置 该漏洞主要用了win10_JAVA的环境,参考网上已有的复现文章,使用jdk-11.0.2_windows-x64_bin.exe 由于2.2.0之后的nacos已将本漏洞修复,所以本次复现使用2.2.0的包 下…...
Elasticsearch集群部署 head监控插件 Kibana部署 Nginx反向代理 Logstash部署
一、组件介绍1、Elasticsearch:2 、Logstash3、Kibana4、Kafka:5、Filebeat: 二、 Elasticsearch集群部署服务器创建用户安装ES修改配置文件创建数据和日志目录设置JVM堆大小 #7.0默认为4G修改安装目录及存储目录权限系统优化(1)增…...
网络和Linux网络_5(应用层)HTTP协议(方法+报头+状态码)
目录 1. HTTP协议介绍 1.1 URL介绍 1.2 urlencode和urldecode 1.3 HTTP协议格式 1.4 HTTP的方法和报头和状态码 2. 代码验证HTTP协议格式 HttpServer.hpp 2.2 html正式测试 Util.hpp index.html 2.3 再看HTTP方法和报头和状态码 2.3.1 方法_GET和POST等 2.3.2 报头…...
人工智能-注意力机制之残差连接和层规范化
残差连接和层规范化 层规范化和批量规范化的目标相同,但层规范化是基于特征维度进行规范化。尽管批量规范化在计算机视觉中被广泛应用,但在自然语言处理任务中(输入通常是变长序列)批量规范化通常不如层规范化的效果好。 以下代…...
linux centos安装nvm
安装目录 mkdir /opt/nvm && cd /opt/nvm安装包下载 wget https://github.com/nvm-sh/nvm/archive/refs/tags/v0.39.5.tar.gz注意:https://github.com/nvm-sh/nvm/tags获取新版本或所需版本下载链接并替换 安装包解压 for file in *.tar.gz; do tar -zxv…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
