2021SC@SDUSC
本篇文章围绕代码模块jpress-service,jpress-service-provider两个包,进行代码的概述与分析。
文章目录
一、模块描述
1.1 模块的功能简述
由JPress官方文档的架构来看,两个模块的结构如下:
jpress-service为页面业务内容(如文章管理、页面管理等)提供非业务service接口定义,jpress-service-provider是非业务service接口的实现。其中会涉及到JPress的非业务实体类jpress-model,这几个包都为业务功能提供了至关重要的功能接口。比如发布文章时附加图片、视频等,需要通过AttachmentServiceProvider
得以实现相关附件的存储和读取;CouponCodeServiceProvider
实现优惠券业务功能的状态实现等等。
1.2 pom.xml
jpress-service,jpress-service-provider所用主要依赖为jboot以及jpress-core,代码如下:
<dependencies>
<dependency>
<groupId>io.jboot</groupId>
<artifactId>jboot</artifactId>
</dependency>
<dependency>
<groupId>io.jpress</groupId>
<artifactId>jpress-model</artifactId>
</dependency>
<dependency>
<groupId>io.jpress</groupId>
<artifactId>jpress-service</artifactId>
</dependency>
<dependency>
<groupId>io.jpress</groupId>
<artifactId>jpress-core</artifactId>
</dependency>
二、AttachmentServiceProvider
2.1 继承与实现
- AttachmentServiceProvider实现AttachmentService接口,实现其中的抽象方法。
- AttachmentServiceProvider继承自JbootServiceBase。
- JbootServiceBase提供Dao层对数据的操作方法,比如
//通过id查找model
public M findById(Object id) {
return this.DAO.findById(id);
}
//以目前的model更新缓存
public boolean update(M model) {
boolean result = model.update();
if (result) {
this.shouldUpdateCache(3, model, model._getIdValue());
}
return result;
}
2.2 函数用途
_paginate(int page, int pagesieze, String title)
输入内容进行标题的模糊查询,并使用paginate分页API进行查询结果的分页,返回查询结果
save(Attachment model)
保存附件内容至数据库对应表格
tryToProcessWatermark(Attachment model)
对附件处理水印,用在上面的save方法中
三、补充 paginate
在函数用途的第一个方法中,我们看到了分页API的使用,并且在JPress之前分析过的模块当中只是简短介绍,在此做详细分析。
3.1 常用 paginate
- Model 与 Db 中提供了最常用的分页API:paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect, Object… paras)
- 其中的参数含义分别为:当前页的页号、每页数据条数、sql语句的select部分、sql语句除了select以外的部分、查询参数。绝大多数情况下使用这个API即可。以下是使用示例:
dao.paginate(1, 10, "select *", "from girl where age > ? and weight < ?", 18, 50);
3.2 sql 最外层带 group by 的 paginate
- API 原型:paginate(int pageNumber, int pageSize, boolean isGroupBySql, String select, String sqlExceptSelect, Object… paras),相对于第一种仅仅多了一个boolean isGroupBySql参数,以下是代码示例:
dao.paginate(1, 10, true, "select *", "from girl where age > ? group by age", 18);
- 以上代码中 sql 的最外层有一个 group by age,所以第三个参数 isGroupBySql 要传入 true 值。
- 如果是嵌套型sql,但是 group by 不在最外层,那么第三个参数必须为 false,例如:select * from (select x from t group by y) as temp。
再次强调:isGroupBy 参数只有在最外层 sql 具有 group by 子句时才能为 true 值,嵌套 sql 中仅仅内层具有 group by 子句时仍然要使用 false。
3.3 paginateByFullSql
- API 原型:paginateByFullSql(int pageNumber, int pageSize, String totalRowSql, String findSql, Object… paras)。
- 相对于其它 paginate API,将查询总行数与查询数据的两条sql独立出来,这样处理主要是应对具有复杂order by语句或者select中带有distinct的情况,只有在使用第一种paginate出现异常时才需要使用该API,以下是代码示例:
String from = "from girl where age > ?";String totalRowSql = "select count(*) " + from;String findSql = "select * " + from + " order by age";dao.paginateByFullSql(1, 10, totalRowSql, findSql, 18);
- 上例代码中的order by子句并不复杂,所以仍然可以使用第一种API搞定。
重点:paginateByFullSql 最关键的地方是 totalRowSql、findSql 这两条 sql 要能够共用最后一个参数 Object… paras,相当于 dao.find(totalRowSql, paras) 与 dao.find(findSql, paras) 都要能正确执行,否则断然不能使用 paginateByFullSql。
四、总结
在本篇文章中,我们深入了解了JPress所用分页实现的底层JFinal的分页APIpaginate,接下来会继续分析jpress-service,jpress-service-provider模块的其他内容,并且都会详细分析代码底层的具体实现。