Mybatis-plus 分页集成以及基本使用总结 入门和案例 注解连表查询分页案例等
简介
Mybaits-plus 是mybits 的升级版,从mybaits 升级到mybaits-plus 可以实现平滑升级
Mybaits-plus 本身提供了大量的基本查询方法以及强大的 Wrapper(包装) 类 用于查询的 QueryWrapper 以及 更新的 UpdateWrapper ,使用Wrapper 基本已经可以构建大部分条件了。
几乎可以实现很少代码,很多功能自动提供
使得一般的查询几乎不需要写 XML 直接使用代码包装完成。
同时支持各类注解帮助完成实体以及查询语句的构建。
环境
spring-boot
Maven 依赖
可以使用properties 的方式指定版本也可以去除perperties 直接写入版本到下面的 version 中
<!-- 版本 --><properties><mybatis-plus.version>3.5.2</mybatis-plus.version><mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version></properties><!-- mybaits-plus 主要依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- MybatisPlus代码生成器 可选,不是必要的--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>${mybatis-plus-generator.version}</version></dependency><!-- MybatisPlus代码生成器默认生成引擎的依赖 可选,不是必要的 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>${velocity.version}</version></dependency>
使用分页时需要添加的配置类
注意下面的导包来源路径,不要导错
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 新增mybatis-plus 插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 新增分页插件 并指定数据库类型PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setOptimizeJoin(true);// 查询分页最大限制 -1 时不做限制paginationInnerInterceptor.setMaxLimit(500L);// 加入分页插件interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}
}
到这里基本完成配置
同时也可以在这里使用注解指出配置的实体类扫描路径和基本Mapper 类的路径
上面也可以如下示例:
@Configuration
// 指定实体类(就是和数据库中表对应的类)扫描路径 类所在包路径
@EntityScan("org.aurora.entity")
// 基本的Mapper 类的所在包路径
@MapperScan(basePackages = "org.aurora.mapper", markerInterface = BaseMapper.class)
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 新增mybatis-plus 插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 新增分页插件 并指定数据库类型PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setOptimizeJoin(true);// 查询分页最大限制 -1 时不做限制paginationInnerInterceptor.setMaxLimit(500L);// 加入分页插件interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}
}
包路径为多个同级目录下的多个mapper 时可以使用 ** 指代所有
例如:org.aurora.**.mapper
说明是 org.aurora 下所有的第一层同级包下,每个包下的 mapper 包下
例如我的测试用包路径如下

同时:上面的
@MapperScan 也可以加到 springboot的启动类上
如下:
(注意:Application 启动类一定在 最外层,从图上可以看出和项目 resources 的层级关系,java 和 resources 同级,该类一定在一层包的最外面一层)

@MapperScan 也可以如下加入
@MapperScan("org.aurora.mapper")
// spring 中其他通过注解等方法注入spring容器的类的扫描路径 一般放到最大的路径上 让扫描整个项目也省事
@ComponentScan(value = {"org.aurora"})
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
@ComponentScan 中的路径最好放在最大的,这样 config 类也能扫描到,否则你可能会发现自己的部分类配置了但是不起作用。
上方 @EntityScan(“org.aurora.entity”) 也可以加入到 spring-boot 配置文件中 而不写在文件里
例如:
在spring-boot 的 application.properties 或者 applicaiton.yml 中如下:
两种文件仅仅是排版格式不同而已,值一致
mybatis-plus 配置中,这里是 yml 如下:
mybatis-plus:
# mybaits 和mybaits-plus 都可以使用的xml 文件类的扫描加载路径mapper-locations: classpath:mapper/*Mapper.xml
# 上面的 EntityScan 可以替代,也可以写在这里typeAliasesPackage: org.aurora.entity
properties类文件可以如下参考
# mybaits 和mybaits-plus 都可以使用的xml 文件类的扫描加载路径
mybatis-plus.mapper-locations = classpath:mapper/*Mapper.xml# 上面的 EntityScan 可以替代,也可以写在这里
mybatis-plus.typeAliasesPackage= org.aurora.entity
mapper-locations:classpath: 后为路径,可以理解为这里扫描 resources 下一个叫 mapper 的文件加里面 所有以 Mapper为文件名后缀的 xml 文件。
一般实体类定义
(在上面定义的实体类扫描路径包下创建)
以下所有注解均来源于mybaits-plus 以及 lombok
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;@TableName("t_person")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PersonEntity {@TableId(type = IdType.AUTO)private Long id;protected boolean flag;@TableField(value="create_time")protected Date createTime;@TableField(value = "person_name")private String personName;@TableField(value = "person_id")private String personId;@TableField(value = "person_pre")private String personPre;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
为lombok 注解用于简化 get set 以及构造方法等,可以使用一般的 get set 构建函数替代而不使用注解
@TableId :
用于指定当前表的主键Id 如果自己设置了自增,不要忘了在建表时也设置主键自增否则会出现保存失败的情况
@TableName:
指定当前表的表名
@TableField:
指定当前属性在表中的字段名称
其中 flag 字段没有指定,可以认为单个单词时不用指定 table_field 默认使用属性名。
建立实体对应的Mapper 接口类 (dao 层)
(在上面指定的Mapper 扫描路径包下定义)
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.aurora.entity.PersonEntity;
import org.springframework.stereotype.Repository;// 定义为持久层 数据库交互
@Repository
public interface PersonMapper extends BaseMapper<PersonEntity> {}
是的 只需要这一点就可以了 这样 Mybaits 就提供了 PersonEntity 对应表的基本查询的所有方法,当然也可以像 mybatis 一样继续定义抽象方法,然后**在 resources 下的 mapper 包内添加对应 Mapper.xml 文件的SQL实现
Mapper 接口类的实际使用
在某一Service 中我可以如下定义
基本新增数据
import org.aurora.mapper.PersonMapper;
import org.aurora.entity.PersonEntity;
import org.aurora.service.PersonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.Date;@Service
@Slf4j
public class PersonServiceImpl implements PersonService {@Autowiredprivate PersonMapper personMapper;@Overridepublic void test() {PersonEntity personEntity = new PersonEntity();personEntity.setFlag(true);personEntity.setCreateTime(new Date());personEntity.setPersonId("*************");personEntity.setPersonName("jack");personEntity.setPersonPre("king");personMapper.insert(personEntity);}
}
这是接口类 继承 BaseMapper<**Entity> 后提供的基本方法,只需要实体即可。

基本查询
继承 baseMapper 后即提供以下查询方法

selectByMap:
入参为普通的 Map 其中 map 的key 需要放入实际表的字段名例如上面的(“person_name”), value 是某一个字段等于的值,相当于普通的条件查询。
selectCount:
该方法为条件下计算总数
入参为 wrapper 类。wrapper 是mybaits-plus 的条件包装类,暂时可以当作Map 但是比 Map 更强大,提供了大于,等于,小于,like 等等,方法介绍完成后下面做具体说明。
selectList:
查询满足某些条件的实体集合。
selectPage:
查询满足某些条件的实体集合。同时支持分页,可以放入分页对象,自动完成分页查询。
分页下面与 wrapper 同时介绍
selectBatchIds:
查询某一个id 集合下的所有实体。
selectById:
通过主键查询
selectMaps:
获取的结果转为 Map 的集合,可以用于单独几个字段或自定义结果查询。
selectMapsPage:
与上面比多了分页而已
selectObjs:
同样的返回自定义结果集合
selectOne:
查询某些条件下唯一的实体
Wrapper 介绍 以及分页的基本使用
查询时使用 QueryWrapper


可以看的出wrapper 提供了很多包装功能,其中入参的 column 为列名,Object 即为值,condition 为当前语句加入实际查询语句的条件可以如下理解:
即最简单的我们某一个值不存在时某一句是不需要加入的,condition 就完成了整个封装过程减少了 if 的判断
eq: 相等
in: 一般的 in 条件
ge: 大于等于
gt: 大于
le: 小于等于
lt: 小于
between : 某一列 在某两个值之间
or: 或者
以及排序

like 模糊查询:

groupBy:

haveing:

一般的使用可以如下参考:

分页查询
示例:
注意Page的来源 也是mybatis-plus 不要用其他的,内部已经提供了总页数,总数,当前页,页容量,
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;@Service
@Slf4j
public class PersonServiceImpl implements PersonService {@Autowiredprivate PersonMapper personMapper;@Overridepublic void test() {String personName = null;Page<PersonEntity> page = new Page<>();// 查询的当前页码 第一页page.setCurrent(1);// 查询条数page.setSize(10);QueryWrapper<PersonEntity> queryWrapper = new QueryWrapper<>();queryWrapper.eq("flag", true);queryWrapper.eq(StringUtils.isNotEmpty(personName), "person_name", personName);queryWrapper.like("person_id", "4567");Page<PersonEntity> pageList = personMapper.selectPage(page, queryWrapper);}
}

更新时 updateWrapper
当使用更新时使用 updateWrapper
但与 queryWrapper 不同的是有 set 方法,即更新某一个字段的值
同样存在 condition 的用法,免去 if 的书写。

例如:

可以看的出可以直接将实体放入后自动通过Id 更新,也可以将wrapper 放入
经过尝试,第一个方法中的entity 可以不放入填写 null ,则会根据 wrapper 中的条件更新所有符合条件的数据。
删除
同样的删除也使用 updateWrapper
方法见名知意,都很简单。

到此所有的基本方法基本都可以无代码自动支持了!
不得不说,真的十分简化操作!
连表查询-连表分页 注解+sql实现
首先需要在 mapper 中额外定义抽象方法
下面第一个为分页,第二个为不分页
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;@Repository
public interface XxxxxMapper extends BaseMapper<XxxxxEntity> {@Select("SELECT r.id, r.dept_id, r.person_id," +"s.secret_name, t.state, f.error FROM t_person AS r "+ " LEFT JOIN t_secret AS s ON r.id = s.per_id "+ " LEFT JOIN t_xxxx AS f ON r.id = f.id "+ " LEFT JOIN t_xxxxxxxx AS t ON f.flow_id = t.id "+ " ${ew.customSqlSegment}")IPage<XxxxxxDTO> getListPageByConditions(IPage<XxxxxxDTO> pageDtoIPage, @Param("ew") Wrapper wrapper);@Select("SELECT r.id, r.dept_id, r.person_id," +"s.secret_name, t.state, f.error FROM t_person AS r "+ " LEFT JOIN t_secret AS s ON r.id = s.per_id "+ " LEFT JOIN t_xxxx AS f ON r.id = f.id "+ " LEFT JOIN t_xxxxxxxx AS t ON f.flow_id = t.id "+ " ${ew.customSqlSegment}")XxxxxxDTO getListByConditions(@Param("ew") Wrapper wrapper);
}
解读:
第一个方法 getListPageByConditions 的分页方法需要我们将 mybatis-plus 的分页对象作为入参传入,外面调用时记得指定分页的当前页码以及页容量。
其他的条件可以通过 queryWrapper 对象传入。
ew.customSqlSegment: ew 为别名 用于识别wrapper 对象,customSqlSegment 为queryWrapper 中的 方法

customSqlSegment 应该是用于获取queryWrapper 构建完成的 SQL 语句,所以在实际queryWrapper 时指定的列名也要用 表别名之类的指定才行
类似于:

这里查询出的字段名可以和对应实体定义的属性名一致即可,最终返回时会自动匹配列名。
例如上面查询了 secret_name 但是实体中我定义的是这样
@TableField(value = "secret_name")private String secretName;
那么返回的自定义类中也使用 secretName 即可。
其他内容后续不定期继续加入,都在同一专题下
相关文章:
Mybatis-plus 分页集成以及基本使用总结 入门和案例 注解连表查询分页案例等
简介 Mybaits-plus 是mybits 的升级版,从mybaits 升级到mybaits-plus 可以实现平滑升级 Mybaits-plus 本身提供了大量的基本查询方法以及强大的 Wrapper(包装) 类 用于查询的 QueryWrapper 以及 更新的 UpdateWrapper ,使用Wrapper 基本已经可以构建大…...
5个设计师常用素材库
推荐5个设计素材网站,免费下载! 1、菜鸟图库 菜鸟图库-免费设计素材下载 菜鸟图库是一个素材量非常丰富的网站,该网站聚合了平面、UI、淘宝电商、高清背景图、图片、插画等高质量素材。平面设计模板非常多,很多都能免费下载&…...
PHP/7.2.11 缺少 apache2/logs/httpd.pid 文件
启动服务时:systemctl restart httpd.service,报错:● httpd.service - httpd serviceLoaded: loaded (/etc/systemd/system/httpd.service; enabled; vendor preset: disabled)Active: failed (Result: exit-code) since 五 2023-02-24 16:1…...
【centos7下部署mongodb】
一.安装环境 CentOS7MongoDB4.0.13正式版。 二.下载MongoDB 1.1 官网下载地址:https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.13.tgz 1.2 将压缩包通过xftp上传到服务器/opt目录,然后解压、改名 三. 配置环境变量及配置文件 3.1配置系…...
pycharm首次使用爬虫框架scrapy遇到的问题和解决方法(二)
在首次使用scrapy框架的过程中,一直是对着别人的框架步骤撸代码的。然而,撸着撸着发现好像别人的也用不了。后面就只能自己找踏坑了。 问题报错: 1,IndexError: list index out of range 2,pymysql.err.ProgrammingError: (1064, "You have an error in your SQL s…...
pyflink学习笔记(二):table_apisql
Joins Inner Join 官网说明:和 SQL 的 JOIN 子句类似。关联两张表。两张表必须有不同的字段名,并且必须通过 join 算子或者使用 where 或 filter 算子定义至少一个 join 等式连接谓词。先创建2个表,两个表的字段是相同的,我想验证…...
嵌入式 STM32 实现STemwin移植+修改其配置文件,驱动LCD显示文本 (含源码,建议收藏)
目录 一、STemwin 简介 二、源码下载 1、在移植STemwin源码之前,需要一个已经具备LCD读写,填充指定颜色等函数功能的一个工程; 2、STemwin 3、源码下载 三、STemwin移植 1、解压源码路径 2、STemwin文件介绍 四、修改配置文件&…...
[计算机网络(第八版)]第一章 概述(学习笔记)
1.1 计算机网络在信息时代中的作用 21世纪是以网络为核心的信息时代,21世纪的重要重要特征:数字化、网络化与信息化。 三大类网络 电信网络:向用户提供电话、电报、传真等服务;有线电视网络:向用户传送各种电视节目&am…...
AI绘图:常用镜头和视角
镜头 Establishing Shot 通过宽广或超宽广的视角交待故事发生的大地理环境 Master Shot 众多人物都能完整地出现在镜头里。 Wide Shot 广角镜头。又称“长镜头” Long Shot。人物全身展现,但在画面中所占比例相对较少 Ultrawide Shot 超广角镜头 Low Angle Sho…...
TCP四次挥手
TCP 四次挥手过程是怎样的? TCP 断开连接是通过四次挥手方式。 双方都可以主动断开连接,断开连接后主机中的「资源」将被释放,四次挥手的过程如下图: 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1…...
Tomcat源码分析-类加载器
类加载器 在分析 tomcat 类加载之前,我们简单的回顾下 java 体系的类加载器 启动类加载器(Bootstrap ClassLoader):加载对象是java的核心类库,把一些的 java 类加载到 jvm 中,它并不是我们熟悉的 ClassLoader&#x…...
MySQL进阶篇之视图/存储过程/触发器
今天我们主要来快速学习视图,存储过程,触发器四个方面的内容,一起加油学习吧,还有半年就有秋招了,要加快速度了,迫在眉睫,冲吧,兄弟们。 目录 1、视图 2、存储过程 3、存储函数 4、…...
【一看就会】实现仿京东移动端页面滚动条布局
简单粗暴直接上代码: <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta http-equiv"X-UA-Compatible" content"IEedge"> <meta name"viewport" content&q…...
网易的“草长莺飞二月天”:增长稳健,加码研发,逐浪AI
2月23日,网易发布了2022年第四季度财报。 这是网易与暴雪分道扬镳后的首份财报,加上近期AIGC热度扩散至游戏、教育等各个领域,网易第四季度业绩及其对于GPT等热门技术的探索受到市场关注。 根据财报,第四季度,网易营…...
NPC内网穿透教程-入门
安装 安装包安装 releases下载 下载对应的系统版本即可,服务端和客户端是单独的 源码安装 安装源码 go get -u ehang.io/nps 编译 服务端go build cmd/nps/nps.go 客户端go build cmd/npc/npc.go docker安装 server安装说明 client安装说明 启动 服务端 下…...
【Linux修炼】14.磁盘结构/文件系统/软硬链接/动静态库
每一个不曾起舞的日子,都是对生命的辜负。 磁盘结构/文件系统/软硬链接/动静态库前言一.磁盘结构1.1 磁盘的物理结构1.2 磁盘的存储结构1.3 磁盘的逻辑结构二.理解文件系统2.1 对IO单位的优化2.2 磁盘分区与分组2.3 分组的管理方法2.4 文件操作三.软硬链接3.1理解硬…...
Spring源码分析:创建 BeanDefinition 流程
一、前期准备1.1 环境依赖<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.7.RELEASE</version></dependency><dependency><groupId&…...
Linux 练习一(思维导图 + 练习过程)
文章目录一、Linux 用户管理及文件操作第一段练习记录:主要对用户进行删除添加设置密码等操作第二段练习记录:主要包括权限设置和查找命令第三段练习记录:关于文件的命令练习第四段练习记录:查找命令及查看内存命令的使用二、Linu…...
高德地图基础教程超详细版
在当前社会,对于地图的使用是很必须的,所以对于程序员来说也是需要掌握的技能,目前主流的又百度地图和高德地图,但是我建议使用高德地图,因为百度地图的API着实不好用吖,不好理解,对于开发人员来…...
基于A7核开发板的串口实现控制LED亮灭
1.通过操作Cortex-A7核,串口输入相应的命令,控制LED灯进行工作 1>例如在串口输入led1on,开饭led1灯点亮 2>例如在串口输入led1off,开饭led1灯熄灭 3>例如在串口输入led2on,开饭led2灯点亮 4>例如在串口输入led2off,开饭led2灯熄灭 5>例如…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...
归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
