Pagination Configuration Using MyBatis-Plus Built-in Support
package com.minster.yanapi.Config;
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 {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
The configuration class declares a package, imports necessary MyBatis-Plus and Spring annotations, and defines a bean that returns a MybatisPlusInterceptor. The interceptor is configured with a PaginationInnerInterceptor set to MySQL data base type, enabling automatic pagination support.
Controller Layer Implementation
@GetMapping()
public ApiResponse<Page<ArticleResp>> getArticleList(@RequestParam("current") Integer current,
@RequestParam("pageSize") Integer pageSize) {
Page<Map<String, Object>> page = new Page<>(current, pageSize);
return yanArticleService.getArticleList(page);
}
The controller method handles GET requests without a specific path extension. It accepts two request parameters: current for the current page number and pageSize for the number of items per page. A Page object with Map<String, Object> type is created using these parameters, then passed to the service layer. The response is wrapped in an ApiResponse containing a Page<ArticleResp>.
Service Layer Transformation and Wrapping
public ApiResponse<Page<ArticleResp>> getArticleList(Page<Map<String, Object>> page) {
Page<Map<String, Object>> result = yanArticleMapper.getArticleList(page);
List<ArticleResp> yanArticles = result.getRecords().stream()
.map(record -> {
ArticleResp articleResp = new ArticleResp();
articleResp.setId((Long) record.get("id"));
articleResp.setTitle((String) record.get("title"));
articleResp.setSummary((String) record.get("summary"));
articleResp.setCreateTime((Date) record.get("createTime"));
articleResp.setUsername((String) record.get("username"));
articleResp.setAvatar((String) record.get("avatar"));
articleResp.setLikeCount((Long) record.get("likeCount"));
articleResp.setCommentCount((Long) record.get("commentCount"));
return articleResp;
})
.collect(Collectors.toList());
Page<ArticleResp> yanArticlePage = new Page<>();
yanArticlePage.setRecords(yanArticles);
yanArticlePage.setCurrent(result.getCurrent());
yanArticlePage.setSize(result.getSize());
yanArticlePage.setTotal(result.getTotal());
yanArticlePage.setPages(result.getPages());
return ApiResponse.success(yanArticlePage);
}
The service method receives a paginated query result from the mapper as Page<Map<String, Object>>. It converts each map record into an ArticleResp object using Java streams, extracting fields such as id, title, summary, createTime, username, avatar, likeCount, and commentCount. A new Page<ArticleResp> is constructed, populated with the transformed records and pagination metadata (current page, size, total, pages), then returned as a succsess response.
Mapper Layer with Custom SQL
@Select("SELECT\n" +
" a.id,\n" +
" a.title ,\n" +
" a.summary ,\n" +
" a.create_time AS createTime,\n" +
" u.username ,\n" +
" d.avatar, \n" +
" COUNT(DISTINCT c.id) AS likeCount ,\n" +
" COUNT(DISTINCT l.id) AS commentCount\n" +
"FROM\n" +
" yan_article a\n" +
"JOIN\n" +
" yan_user u ON a.author_id = u.id\n" +
"LEFT JOIN\n" +
" yan_details d ON u.detail_id = d.id\n" +
"LEFT JOIN\n" +
" yan_comment c ON a.id = c.article_id\n" +
"LEFT JOIN\n" +
" yan_like l ON a.id = l.article_id\n" +
"GROUP BY\n" +
" a.id, a.title, a.summary, a.create_time, u.username, d.avatar")
Page<Map<String, Object>> getArticleList(Page<Map<String, Object>> page);
The mapper method uses the @Select annotation with a custom SQL query. The query joins the yan_article table (alias a) with yan_user (u) and performs left joins on yan_details (d), yan_comment (c), and yan_like (l). It counts distinct comment IDs and like IDs to derive likeCount and commentCount. Results are grouped by article and user-related columns. The returned type is Page<Map<String, Object>>, where each map corresponds to a row with fields: id, title, summary, createTime, username, avatar, likeCount, commentCount.