# ken-page-pom
**Repository Path**: gitee-xk/ken-page-pom
## Basic Information
- **Project Name**: ken-page-pom
- **Description**: No description available
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 25
- **Created**: 2021-11-05
- **Last Updated**: 2022-05-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
[TOC]
### 一、ken-page
> 1、一款基于Mybatis的分页插件
> 2、可以兼容原生MyBatis、tk-Mybatis以及Mybatis-Plus等主流框架
> 3、解决复杂关联查询导致分页错误的问题
> 4、配合Web层拦截,实现无侵入式分页
### 二、分页基本使用
添加依赖
```xml
io.github.verygoodwlk
ken-page-boot-starter
1.2.6
```
开启分页 - 在业务合适的地方,调用以下代码开启分页
```java
//pageNum - 当前页码
//pageSize - 每页显示多少条
//注意:这行代码后,当前业务的所有数据库查询操作都将自动实现分页效果
KenPages.setPage(pageNum, pageSize);
```
查询后获取分页信息(总条数、总页码等数据)
```java
//分页的相关信息
Page page = KenPages.getPage();
int count = page.getCount(); //获得总记录数
int totle = page.getTotle(); //总页数
```
> 注意:因为分页插件的无侵入设计,可以随时停止所有分页的功能。只需在application.yml中配置即可
```yml
#关闭分页功能 - 分页的业务会自动变成查询全部,默认开启
kenplugin:
page:
enable: false
```
### 三、SQL执行监控功能
> 插件自带SQL执行记录以及耗时监控功能,所有运行的sql语句以及相关参数还有耗时时间都将被日志记录
```
[SQL] executor - [select * from test where id = ?]
[SQL] params[0] - [id:5]
[SQL] take up time - [0.013s]
```
关闭SQL执行监控,只需要在application.yml配置即可
```yml
#关闭SQL记录,默认开启
kenplugin:
execsql:
enable: false
```
### 四、复杂业务定制化分页
> 在一些复杂的业务中,可能存在多个子业务,有些子业务可能需要分页,有些子业务不需要,则可以使用定制化分页的功能
开启分页定制化
```java
//参数二:表示开启定制化分页,默认关闭
KenPages.setPage(pageNum, pageSize, true);
```
标记分页注解 - 通常在子业务方法或者mapper接口方法上标记
```java
主业务方法(){
//开启分页
KenPages.setPage(pageNum, pageSize, true);
//子业务1方法
//子业务2方法
//子业务3方法
//子业务4方法
}
子业务1方法(){
}
@Paging
子业务2方法(){
}
子业务3方法(){
}
@Paging
子业务4方法(){
}
```
> 当前模式下,只有标注了@Paging注解的业务,才会受到分页的影响
> @Paging注解可以直接标记在Mapper接口的方法上
### 五、多表关联SQL分页
> 实际开发过程中,SQL可能会关联多张表查询,导致查出来的分页结果会存在数量不足的问题,比如
```sql
select * from
table1 t join table2 t2 on t1.id = t2.tid
```
> 以上这条SQL,本意是讲table1作为主表,关联查询出table2的结果,table2的结果作为子集放入到table1对应的记录中。
> 此时,如果要分页,应该是对table1表进行分页,但是因为关联的存在,实际table1查询出来的记录,并不会满足当前页的记录数。
**解决方案**
> 我们需要调整下SQL的结构
```sql
select * from
(select * from table1 limite ?) t join table2 t2 on t.id = t2.tid
```
> table1作为主表,我们可以人为将主表的查询部分独立出来,然后在主表查询后面跟上limit ?,
> 插件会自动判别到该部分为主表查询,会先对该部分分页,再将分页出来的结果去关联其他表,
> 这样就会得到正确的分页结果。实际情况可能比这个复杂的多,所以需要开发者根据实际的业务去动态调整SQL语句的结构。
### 六、Web层自动化兼容分页
开启Web层分页兼容配置(默认关闭)
```yml
#开启web层分页兼容配置
kenplugin:
page:
webconfig:
enable: true
```
客户端传递分页参数
```http request
#pageNum - 当前页
#pageSize - 每页显示多少条
http://server.com/xxxx?pageNum=1&pageSize=5
```
> 开启web层兼容分页后,只需要客户端传递分页参数,后续业务会自动化完成分页,
> 无需再使用KenPages.setPage(new Page(pageNum, pageSize));方法来开启分页。
>
>业务复杂的情况下,仍然可以使用@Paging注解实现定制化分页
定制分页参数名称
> 当不想使用pageNum和pageSize作为参数名称时,可以定制名称
```yml
kenplugin:
page:
key:
#定制当前页的参数名称
num: pageNo
#定制每页条数的参数名称
size: pageS
#定制返回的总条数参数名称
count: pageCount
#定制返回的总页码数参数名称
total: pageTotal
```
返回分页信息给客户端
> Web层(Controller方法)返回的对象必须继承BaseResult类,比如
```java
class OutPut extends BaseResult{
Integer code;
String msg;
T datas;
}
@RequestMapping("/xxx/xxx")
public OutPut> xxxx(){
}
```
> 客户端会收到如下的结果数据:
```json
{
//分页信息 - 属性名称通过上面的参数可自定义(不设置则采用默认参数名称)
"page": {
"pageNo": 1,
"pageS": 2,
"pageCount": 25,
"pageTotal": 13
},
"code": 200,
"message": "请求成功",
"data": [
{
//数据部分....
}
]
}
```
### 七、复杂查询的自动映射功能 - (测试中)
> 实际开发过程中,可能会面临很多关联查询,这些查询结果需要映射到实体类集合中,为了实现嵌套映射,往往开发者需要编写大量的 ResultMap 标签内容来手动构建查询结果和实体类的映射关系。
> 自动映射功能并不是原来单纯的单表映射,而是可以借助注解轻松实现多表关联查询的自动映射。
> 注意:
> 1、该功能目前处于测试阶段,如果有任何问题可以直接关闭或者局部关闭,不影响原来正常功能的使用
> 2、该功能目前需要配合Mybatis-plus插件一起使用,原生或其他框架暂时不支持
> 3、该功能对Mybatis底层侵入较深,会影响一定的性能,请慎用,后续版本会进行性能优化
> 使用步骤
开启自动映射功能
```yml
#开启自动映射功能(默认关闭)
kenplugin:
auto:
mapping:
enable: true
```
编写Mapper.xml中的SQL语句
```xml
```
配置实体类
```java
//采用lombok简化开发,可以无视
@Data
@Accessors(chain = true)
public class Test implements Serializable {
//使用mybatis-plus标签标识主键,如果数据库主键名称和当前字段名称不相同,可以通过value属性设置
@TableId(type = IdType.AUTO)
private Integer id;
//未标识的字段,默认和数据库同名列映射
private Integer age;
//如果数据库字段名称和当前字段名称不相同,可以通过@TableField注解value属性设置
//还可以通过该注解设置该列的typeHandler等属性
@TableField("p_name")
private String name;
//防止插入报错,告诉Mybatis-plus忽略该字段
@TableField(exist = false)
//标识对多映射,指定对多的集合体中实际的类型
//如果是对一映射,可以使用@ToOne注解即可
@ToMore(type = Test2.class)
private List likes;
}
//关联的实体类 多的一方
@Data
@Accessors(chain = true)
public class Test2 implements Serializable {
@TableId(type = IdType.AUTO)
//需要注意,如果两个表的主键同名,需要通过@IdAlias注解设置一个别名id和数据库的主键映射,SQL语句中也必须指定id别名
@IdAlias("lid")
private Integer id;
private Integer uid;
private String likes;
private Date likeTime;
}
```
添加查询注解
```java
//标注@AutoMapping的方法,才会启动自动映射的功能,起到一个局部控制的作用
@AutoMapping
List queryAll();
```
执行查询查看结果
```json
...
"data": [
{
"id": 1,
"name": "小明",
"age": 18,
"likes": [
{
"id": 5,
"uid": 1,
"likes": "篮球",
"likeTime": "2007-09-08"
},
{
"id": 7,
"uid": 1,
"likes": "乒乓球",
"likeTime": "2005-01-07"
},
...
]
},
...
]
...
```