我的点赞功能(完整分页查询步骤)和快速刷题开发

文章目录

1.我的点赞分页展示

1.分页查询工具类
1.PageInfo.java 需要分页查询的就继承它,传值的时候pageNo和pageSize可以为空
package com.sunxiansheng.subject.application.newpage;

import java.util.Objects;

/**
 * Description: 分页请求的入参
 * @Author sun
 * @Create 2024/5/28 16:25
 * @Version 1.1
 */
public class PageInfo {

    private Integer pageNo = 1;
    private Integer pageSize = 20;

    public Integer getPageNo() {
        return (pageNo == null || pageNo < 1) ? 1 : pageNo;
    }

    public Integer getPageSize() {
        return (pageSize == null || pageSize < 1) ? 20 : pageSize;
    }

    public PageInfo setPageNo(Integer pageNo) {
        this.pageNo = pageNo;
        return this;
    }

    public PageInfo setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
        return this;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PageInfo pageInfo = (PageInfo) o;
        return Objects.equals(pageNo, pageInfo.pageNo) &&
                Objects.equals(pageSize, pageInfo.pageSize);
    }

    @Override
    public int hashCode() {
        return Objects.hash(pageNo, pageSize);
    }

    @Override
    public String toString() {
        return "PageInfo{" +
                "pageNo=" + pageNo +
                ", pageSize=" + pageSize +
                '}';
    }
}

2.PageResult.java 根据条件从数据库中查询信息,然后设置这里的四个值即可得到分页查询结果
package com.sunxiansheng.subject.application.newpage;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Description: 分页返回的实体
 * @Author sun
 * @Create 2024/5/28 16:36
 * @Version 1.1
 */
public class PageResult<T> {

    // 当前页码,默认为1
    private Integer pageNo = 1;

    // 每页显示的记录数,默认为20
    private Integer pageSize = 20;

    // 总记录条数
    private Integer total = 0;

    // 总页数
    private Integer totalPages = 0;

    // 当前页的记录列表
    private List<T> result = Collections.emptyList();

    // 表示当前页是从分页查询结果的第几条记录开始,下标从1开始
    private Integer start = 1;

    // 表示当前页是从分页查询结果的第几条记录结束,下标从1开始
    private Integer end = 0;

    // ==================== 分页查询只需要设置这几个值即可 ====================

    // 设置当前页码,并重新计算起始和结束位置
    public PageResult<T> setPageNo(Integer pageNo) {
        this.pageNo = Objects.requireNonNull(pageNo, "Page number cannot be null");
        calculateStartAndEnd();
        return this;
    }

    // 设置每页记录数,并重新计算起始和结束位置
    public PageResult<T> setPageSize(Integer pageSize) {
        this.pageSize = Objects.requireNonNull(pageSize, "Page size cannot be null");
        calculateStartAndEnd();
        return this;
    }

    // 设置当前页的记录列表
    public PageResult<T> setRecords(List<T> result) {
        this.result = Objects.requireNonNull(result, "Result list cannot be null");
        return this;
    }

    // 设置总记录条数,并重新计算总页数和起始结束位置
    public PageResult<T> setTotal(Integer total) {
        this.total = Objects.requireNonNull(total, "Total count cannot be null");
        calculateTotalPages();
        calculateStartAndEnd();
        return this;
    }

    // ==================== 分页查询只需要设置这几个值即可 ====================

    // 计算总页数
    private void calculateTotalPages() {
        if (this.pageSize > 0) {
            this.totalPages = (this.total / this.pageSize) + (this.total % this.pageSize == 0 ? 0 : 1);
        } else {
            this.totalPages = 0;
        }
    }

    // 计算起始和结束位置
    private void calculateStartAndEnd() {
        if (this.pageSize > 0) {
            this.start = (this.pageNo - 1) * this.pageSize + 1;
            this.end = Math.min(this.pageNo * this.pageSize, this.total);
        } else {
            this.start = 1;
            this.end = this.total;
        }
    }

    public Integer getStart() {
        return start;
    }

    // 获取每页记录数
    public Integer getPageSize() {
        return pageSize;
    }

    public Integer getPageNo() {
        return pageNo;
    }

    public Integer getTotal() {
        return total;
    }

    public Integer getTotalPages() {
        return totalPages;
    }

    public List<T> getResult() {
        return result;
    }

    public Integer getEnd() {
        return end;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PageResult<?> that = (PageResult<?>) o;
        return Objects.equals(pageNo, that.pageNo) &&
                Objects.equals(pageSize, that.pageSize) &&
                Objects.equals(total, that.total) &&
                Objects.equals(totalPages, that.totalPages) &&
                Objects.equals(result, that.result) &&
                Objects.equals(start, that.start) &&
                Objects.equals(end, that.end);
    }

    @Override
    public int hashCode() {
        return Objects.hash(pageNo, pageSize, total, totalPages, result, start, end);
    }

    @Override
    public String toString() {
        return "PageResult{" +
                "pageNo=" + pageNo +
                ", pageSize=" + pageSize +
                ", total=" + total +
                ", totalPages=" + totalPages +
                ", result=" + result +
                ", start=" + start +
                ", end=" + end +
                '}';
    }
}
2.sun-club-application-controller
1.SubjectLikedDTO.java 继承PageInfo

image-20240624150131012

2.SubjectLikedController.java 获取PageNo和PageSize(可以为空,因为PageInfo有默认值)
/**
 * 分页查询我的点赞列表
 */
@PostMapping("/getSubjectLikedPage")
public Result<PageResult<SubjectLikedDTO>> getSubjectLikedPage(@RequestBody SubjectLikedDTO subjectLikedDTO) {
    try {
        // 打日志
        if (log.isInfoEnabled()) {
            log.info("SubjectController.getSubjectLikedPage.dto:{}", JSON.toJSONString(subjectLikedDTO));
        }
        // 校验参数:这里的pageNo和pageSize可以不填,因为在PageInfo中已经有默认值了
        // 转换DTO为BO
        SubjectLikedBO subjectLikedBO = SubjectLikedDTOConverter.INSTANCE.convertDTOToBO(subjectLikedDTO);
        // 设置分页查询的页码和每页显示的数量,即使为空也没事,因为在BO中已经有默认值了
        subjectLikedBO.setPageNo(subjectLikedDTO.getPageNo());
        subjectLikedBO.setPageSize(subjectLikedDTO.getPageSize());
        // 调用domain层的方法,进行分页查询
        PageResult<SubjectLikedBO> boPageResult = subjectLikedDomainService.getSubjectLikedPage(subjectLikedBO);
        return Result.ok(boPageResult);
    } catch (Exception e) {
        log.error("SubjectCategoryController.getSubjectLikedPage.error:{}", e.getMessage(), e);
        return Result.fail("分页查询我的点赞失败");
    }
}
3.sun-club-domain
1.SubjectLikedBO.java 继承PageInfo

image-20240624155408224

2.SubjectLikedDomainService.java
/**
 * 分页查询我的点赞列表
 * @param subjectLikedBO
 * @return
 */
PageResult<SubjectLikedBO> getSubjectLikedPage(SubjectLikedBO subjectLikedBO);
3.SubjectLikedDomainServiceImpl.java
@Override
public PageResult<SubjectLikedBO> getSubjectLikedPage(SubjectLikedBO subjectLikedBO) {
    // 分页查询的结果
    PageResult<SubjectLikedBO> pageResult = new PageResult<>();
    // 链式调用:设置pageNo和pageSize
    pageResult.setPageNo(subjectLikedBO.getPageNo()).setPageSize(subjectLikedBO.getPageSize());

    // ==========根据条件去db分页查询并设置分页查询结果和total==========
    // 1. 计算起始位置:(pageNo - 1) * pageSize 也就是数据库中的OFFSET,即从第几条开始
    int offset = (subjectLikedBO.getPageNo() - 1) * subjectLikedBO.getPageSize();
    // 2.得到页面大小pageSize 也就是数据库中的LIMIT,即取多少条
    int limit = subjectLikedBO.getPageSize();
    // 3.根据条件查询总数,如果为0,直接返回,这样total默认是0,records也是空的
    SubjectLiked subjectLiked = SubjectLikedBOConverter.INSTANCE.convertBOToEntity(subjectLikedBO);
    subjectLiked.setLikeUserId(LoginUtil.getLoginId());
    int count = subjectLikedService.countByCondition(subjectLiked);
    if (count == 0) {
        return pageResult;
    }
    // 4.如果记录条数不为0根据条件、limit、offset去db分页查询
    List<SubjectLiked> subjectLikedList = subjectLikedService.queryPage(subjectLiked, offset,
            limit);
    // 5.链式调用:设置分页查询结果和total
    List<SubjectLikedBO> subjectInfoBOS = SubjectLikedBOConverter.INSTANCE.convertListInfoToBO(subjectLikedList);
    // 根据subjectId查询subjectName
    subjectInfoBOS.forEach(info -> {
        SubjectInfo subjectInfo = subjectInfoService.queryById(info.getSubjectId());
        info.setSubjectName(subjectInfo.getSubjectName());
    });
    pageResult.setRecords(subjectInfoBOS).setTotal(count);
    // ==========根据条件去db分页查询并设置分页查询结果和total==========
    return pageResult;
}
4.sun-club-infra
1.SubjectLikedService.java
/**
 * 根据条件查询数量
 * @param subjectLiked
 * @return
 */
int countByCondition(SubjectLiked subjectLiked);

/**
 * 分页查询
 * @param subjectLiked
 * @param start
 * @param pageSize
 * @return
 */
List<SubjectLiked> queryPage(SubjectLiked subjectLiked, int start, Integer pageSize);
2.SubjectLikedServiceImpl.java
@Override
public int countByCondition(SubjectLiked subjectLiked) {
    return this.subjectLikedDao.countByCondition(subjectLiked);
}

@Override
public List<SubjectLiked> queryPage(SubjectLiked subjectLiked, int offset, Integer limit) {
    return this.subjectLikedDao.queryPage(subjectLiked, offset, offset);
}
3.SubjectLikedDao.java
int countByCondition(SubjectLiked subjectLiked);

List<SubjectLiked> queryPage(@Param("entity") SubjectLiked subjectLiked,
                             @Param("offset") int offset,
                             @Param("limit") Integer limit);
4.SubjectLikedDao.xml
<select id="countByCondition" resultType="java.lang.Integer">
    select count(1)
    from subject_liked
    where like_user_id = #{likeUserId} and status = 1
      and is_deleted = 0
</select>

<select id="queryPage" resultType="com.sunxiansheng.subject.infra.basic.entity.SubjectLiked">
    select *
    from subject_liked
    where like_user_id = #{entity.likeUserId}
      and is_deleted = 0 and status = 1
        limit #{offset}
        , #{limit}
</select>
5.测试
1.登录

image-20240624160716538

2.点赞

image-20240624163311783

3.使用定时任务将点赞信息同步到数据库

image-20240624163948126

4.查询点赞信息发现查不出来,原因是同步点赞信息时没有设置is_delete=0,设置之后重新测试一遍

image-20240624164354096

image-20240624164435131

5.同步成功

image-20240624164703350

6.total正确了但是没数据,发现是参数写错了,真醉了

image-20240624165012345

7.再次测试,终于对了

image-20240624165438824

2.快速刷题

1.sun-club-application-controller
1.SubjectInfoDTO.java 新增上一题和下一题字段
/**
 * 上一题id
 */
private Long lastSubjectId;

/**
 *
 * 下一题id
 */
private Long nextSubjectId;
2.sun-club-domain
1.SubjectInfoBO.java 新增上一题下一题字段
/**
 * 上一题id
 */
private Long lastSubjectId;

/**
 *
 * 下一题id
 */
private Long nextSubjectId;
2.SubjectInfoDomainServiceImpl.java 将上一题和下一题的id设置到bo中

image-20240624174843066

/**
 * 将上一题和下一题的id设置到bo中
 *
 * @param bo 这个bo是从数据库查出来的信息,是要返回的bo
 * @param subjectInfoBO 这个bo是前端传过来的有信息
 */
private void assembleSubjectCursor(SubjectInfoBO bo, SubjectInfoBO subjectInfoBO) {
    // 得到题目的分类和标签id,因为所有的题目都是基于某个分类,某个标签下的
    Long labelId = subjectInfoBO.getLabelId();
    Long categoryId = subjectInfoBO.getCategoryId();
    Long subjectId = subjectInfoBO.getId();
    // 做好兼容,如果不是快速刷题,前端就不会传递两个id,就直接返回
    if (Objects.isNull(labelId) || Objects.isNull(categoryId)) {
        return;
    }
    // 查询下一题,1表示查询上一题
    Long nextSubjectId = subjectInfoService.querySubjectIdCursor(subjectId, categoryId, labelId, 1);
    bo.setNextSubjectId(nextSubjectId);
    // 查询上一题,0表示查询上一题
    Long lastSubjectId = subjectInfoService.querySubjectIdCursor(subjectId, categoryId, labelId, 0);
    bo.setLastSubjectId(lastSubjectId);
}
3.sun-club-infra
1.SubjectJudgeService.java
/**
 * 查询上一题或者下一题
 * @param subjectId
 * @param categoryId
 * @param labelId
 * @param i 1是查询下一题,0是查询上一题
 * @return
 */
Long querySubjectIdCursor(Long subjectId, Long categoryId, Long labelId, int i);
2.SubjectInfoServiceImpl.java
@Override
public Long querySubjectIdCursor(Long subjectId, Long categoryId, Long labelId, int i) {
    return this.subjectInfoDao.querySubjectIdCursor(subjectId, categoryId, labelId, i);
}
3.SubjectInfoDao.java
    /**
     * 查询上一题下一题
     * @param subjectId
     * @param categoryId
     * @param labelId
     * @param cursor 1是下一题,0是上一题
     * @return
     */
    Long querySubjectIdCursor(@Param("subjectId") Long subjectId,
                              @Param("categoryId") Long categoryId,
                              @Param("labelId") Long labelId,
                              @Param("cursor") int cursor);
4.SubjectInfoDao.xml 查询上一题和下一题的sql
<select id="querySubjectIdCursor" resultType="java.lang.Long">
    select a.id
    from subject_info a
    join subject_mapping b on a.id = b.subject_id
    where b.category_id = #{categoryId}
    and b.label_id = #{labelId}
    <if test="cursor != null and cursor == 1">
        and a.id &gt; #{subjectId}
    </if>
    <if test="cursor != null and cursor == 0">
        and a.id &lt; #{subjectId}
    </if>
    order by a.id
    <if test="cursor != null and cursor == 0">
        desc
    </if>
    limit 1
</select>
4.测试
1.新增同一分类同一标签下的三个题目

image-20240624173912761

2.找到第二个题目的题目id,发送请求

image-20240624174038067

3.查询564得到563和565,没问题

image-20240624174551651

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

S-X-S

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值