遇到的问题

mybatis-plus的单表增删改查的效率是极高的,但是当我做项目的时候出现这样一个需求时

数据库有两张表:用户表,文章表(记录了用户的id)

后端需要查询最新的十条文章,并查询发表文章的用户姓名和用户头像地址

解决办法一

使用mybatis-plus的base查询,查询出所有文章后,再循环查询用户的信息。代码如下

java
1
2
3
4
5
6
7
8
Page<Article> page = query().ge("created_time", DateUtil.lastMonth()).orderByDesc("article.article_like_count").page(new Page<>(current, MAX_PAGE_SIZE));
// 1.获取当前页数据
List<Article> records = page.getRecords();
// 2.查询是否被点赞了
records.forEach(article -> {
this.queryArticleUser(article);
this.isArticleLiked(article);
});

这样的做法最简单,但是需要多次查询mysql,对于首页文章需要经常访问,这样会严重影响效果。因此引出解决方法二

解决办法二

因为考虑到需要给前端返回的是page对象,所以还是需要自带的.page功能。

这里我选择了修改ArticleMapper.xml文件。

对于.page查询时,都会跳转到自定义的mapper查询。

xml
1
2
3
4
5
6
7
8
9
<select id="selectPage" resultType="com.yxz.wulibibiji.entity.Article">
SELECT
article_id,article_title,article_content,
article_view_count,article_like_count,article_comment_count,
created_time,update_time,article_img,
is_deleted,article_category_id,article_user_id,
article_category_name, nickname as `name`, avatar
FROM `article` LEFT JOIN `user` ON user.user_id=article.article_user_id
</select>

优势:对于上述需求,只需要查询一次数据库。

缺点:在后续使用中发现,所有的查询只要接了.page,就会跳转到此mapper查询,且其他拼接的条件都会失效。即:无法自定义sql条件并连表查

解决办法三

对于上述问题,查询解决方法后,自己定义新的mapper查询

对于ArticalMapper.xml文件

xml
1
2
3
4
5
6
7
8
9
<select id="listJoinInfoPages" resultType="com.yxz.wulibibiji.entity.Article">
SELECT
article_id,article_title,article_content,
article_view_count,article_like_count,article_comment_count,
created_time,update_time,article_img,
is_deleted,article_category_id,article_user_id,
article_category_name, nickname as `name`, avatar
FROM `article` LEFT JOIN `user` ON user.user_id=article.article_user_id ${ew.customSqlSegment}
</select>

注意 ${ew.customSqlSegment} 就是warpper会拼接的sql条件,注意和前面字母需要空格。

ArticleMapper.java文件

java
1
2
3
4
@Mapper
public interface ArticleMapper extends BaseMapper<Article> {
IPage<Article> listJoinInfoPages(IPage<Article> page, @Param(Constants.WRAPPER) Wrapper<Article> queryWrapper);
}

ArticleServiceImpl.java文件

java
1
2
3
4
5
6
7
// 1.获取当前页数据
QueryWrapper<Article> wrapper = new QueryWrapper<>();
wrapper.eq("is_deleted", 0).orderByDesc("created_time");
IPage<Article> page = articleMapper.listJoinInfoPages(new Page<>(current, MAX_PAGE_SIZE), wrapper);
page.getRecords().forEach(article -> {
this.isArticleLiked(article);
});

成功解决了自定义sql条件,并链表查。