获取一个表中当前条术和总条数的实现

本文讨论了如何在SpringBoot应用中,通过调整Repository和Service层,实现根据自增ID的排序以及计算符合条件的总记录数,同时探讨了减少数据库查询次数的潜在优化策略,包括单次查询和原生SQL的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果需求是根据自增主键 id 的排序来确定当前记录是第几条,以及计算符合条件的总记录数,我们可以对之前的设计进行适当的调整。这里,我们会修改 Repository 层的方法以确保基于 id 的排序,并更新 Service 层以反映这一变化。

Repository 层

修改 MmScenesContentRepository 接口,以确保查询结果根据 id 排序。我们假设你想要按照 id 升序排序所有记录:

import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;

public interface MmScenesContentRepository extends JpaRepository<MmScenesContent, Long> {
    List<MmScenesContent> findByScenesIdOrderByIDAsc(Long scenesId);
}

Service 层

更新 MmScenesContentService 服务,利用 id 进行排序和定位计算。这里的逻辑是查找给定场景 scenesId 的所有内容,并按照 id 排序,然后确定特定 identifierId 的位置:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class MmScenesContentService {

    @Autowired
    private MmScenesContentRepository repository;

    public SceneContentInfo getSceneContentInfo(Long scenesId, String identifierId) {
        List<MmScenesContent> contents = repository.findByScenesIdOrderByIDAsc(scenesId);
        
        int position = 1; // 默认为第一条
        if (identifierId != null) {
            for (int i = 0; i < contents.size(); i++) {
                if (contents.get(i).getIdentifierId().equals(identifierId)) {
                    position = i + 1;
                    break;
                }
            }
        }

        SceneContentInfo info = new SceneContentInfo(position, contents.size());
        return info;
    }
}

SceneContentInfo DTO

SceneContentInfo DTO 不需要改变,因为它只是用来传输位置信息和总数。

Controller 层

Controller 层的代码也不需要改变,因为它只负责调用 Service 层的 getSceneContentInfo 方法并返回结果。

通过这种方式,我们确保了查询结果根据 id 的自增顺序进行排序,从而可以基于这个排序来计算每条记录的位置。这样,即使在并发创建记录的情况下,每个记录的位置也能正确地反映出它在数据库中的顺序。

确实,前面提出的优化虽然减少了应用层的负载,但引入了两次数据库查询,这对于某些情况下可能不是最佳选择,特别是当数据库查询成本较高时。一个更加优化的方案是尽量减少数据库查询的次数。

如果我们的目标是在单个查询中尽可能地完成工作,我们可以考虑使用原生 SQL 或 JPQL 来执行一个更复杂的查询,该查询旨在一次性返回我们需要的所有信息。不过,这种方法可能需要牺牲一些可读性和维护性,因为复杂的查询通常比简单的查询难以理解和维护。

下面提供一个理论上的解决方案,它基于单次查询来获取位置和总数,但实际实现将取决于你的数据库类型和具体架构。

Service 层

在这个示例中,我们假设能够通过某种方式一次性获取到位置和总数,这可能需要你根据实际使用的数据库来调整 SQL 语句。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MmScenesContentService {

    @Autowired
    private MmScenesContentRepository repository;

    public SceneContentPageInfo getSceneContentInfo(Long scenesId, String identifierId) {
        // 假设这个方法可以通过一个复杂的查询获取到所需的所有信息
        SceneContentPageInfo pageInfo = repository.findPositionAndTotal(scenesId, identifierId);
        return pageInfo;
    }
}

Repository 层

你可能需要使用 @Query 注解来执行一个原生 SQL 查询,该查询能够一次性计算出特定记录的位置以及总数。具体的 SQL 语句将依赖于你的数据库类型(比如 MySQL, PostgreSQL 等),这里仅提供一个概念性的框架,实际的实现需要你根据自己的数据库结构和 SQL 能力进行设计。

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface MmScenesContentRepository extends JpaRepository<MmScenesContent, Long> {

    @Query(value = "SELECT position, total FROM (SELECT id, RANK() OVER (ORDER BY id ASC) AS position, COUNT(*) OVER() AS total FROM mm_scenes_content WHERE scenes_id = :scenesId) AS subquery WHERE id = (SELECT id FROM mm_scenes_content WHERE identifier_id = :identifierId)", nativeQuery = true)
    SceneContentPageInfo findPositionAndTotal(@Param("scenesId") Long scenesId, @Param("identifierId") String identifierId);
}

请注意,上面的 SQL 语句是伪代码,用于展示可能的查询结构。具体实现将需要根据你的数据库类型和需求调整。此外,SceneContentPageInfo 类可能需要相应地调整以映射查询结果。

这种方法尝试在单个查询中完成所有工作,减少了数据库访问次数,但代价是增加了查询的复杂性和对特定数据库特性的依赖。在实际应用中,你需要根据实际情况权衡使用简单查询与应用层处理相结合的方法,还是使用复杂的单次查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

MonkeyKing.sun

对你有帮助的话,可以打赏

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

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

打赏作者

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

抵扣说明:

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

余额充值