JavaWeb后端基础(5)

这一篇主要是web中数据库操作SQL语句怎么写的 多表关系(1对多 1对1 多对多) 以及多表查询(内连接、外连接、子查询)这篇我会重点记一下分页查询。

分页查询

我觉得最重要的就是要明白前端能给你什么参数,以及你返回给前端的是什么参数

后台给前端返回的数据包含:List集合(数据列表)、total(总记录数)。而这两部分我们通常封装到PageResult对象中,并将该对象转换为json格式的数据响应回给浏览器。

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageResult {
        private Long total; //总记录数
        private List rows; //当前页数据列表
}

我们先只考虑分页查询 不考虑查询条件

java 复制代码
@Slf4j
@RequestMapping("/emps")
@RestController
public class EmpController {
        
    @Autowired
    private EmpService empService;
        
    @GetMapping
    public Result page(@RequestParam(defaultValue = "1") Integer page ,
                       @RequestParam(defaultValue = "10") Integer pageSize){
        log.info("查询员工信息, page={}, pageSize={}", page, pageSize);
        PageResult pageResult = empService.page(page, pageSize);
        return Result.success(pageBean);
    }
        
}

@RequestParam

@RequestParam 括号里可以设置的参数有以下几个:

value 或 name 指定请求中参数的名称。如果不写,默认使用方法参数的名称

java 复制代码
@RequestParam("username") String name

required 指定该参数是否必须,默认值是 true。如果设为 false,参数可选,缺失时值为 null 或默认值

java 复制代码
@RequestParam(value = "age", required = false) Integer age

defaultValue指定参数缺失时的默认值。如果设置了默认值,required 会隐式变为 false

java 复制代码
@RequestParam(value = "page", defaultValue = "1") int page
java 复制代码
@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Override
    public PageResult page(Integer page, Integer pageSize) {
        //1. 获取总记录数
        Long total = empMapper.count();

        //2. 获取结果列表
        Integer start = (page - 1) * pageSize;
        List<Emp> empList = empMapper.list(start, pageSize);

        //3. 封装结果
        return new PageResult(total, empList);
    }
}

PageHelper分页插件

分页查询的思路、步骤是比较固定的。 在Mapper接口中定义两个方法执行两条不同的SQL语句:

  1. 查询总记录数

  2. 指定页码的数据列表

在Service当中,调用Mapper接口的两个方法,分别获取:总记录数、查询结果列表,然后在将获取的数据结果封装到PageBean对象中。

如果使用PageHelper插件

  • Mapper接口层:

    • 原始的分页查询功能中,我们需要在Mapper接口中定义两条SQL语句。

    • PageHelper实现分页查询之后,只需要编写一条SQL语句,而且不需要考虑分页操作,就是一条正常的查询语句。

  • Service层:

    • 需要根据页码、每页展示记录数,手动的计算起始索引。

    • 无需手动计算起始索引,直接告诉PageHelper需要查询那一页的数据,每页展示多少条记录即可。

java 复制代码
@Override
public PageResult page(Integer page, Integer pageSize) {
    //1. 设置分页参数
    PageHelper.startPage(page,pageSize);

    //2. 执行查询
    List<Emp> empList = empMapper.list();
    Page<Emp> p = (Page<Emp>) empList;

    //3. 封装结果
    return new PageResult(p.getTotal(), p.getResult());
}

实现机制:

执行了两条SQL语句,而这两条SQL语句,其实是从我们在Mapper接口中定义的SQL演变而来的

其实就是将我们编写的SQL语句进行的改造增强,将查询返回的字段列表替换成了 count(0) 来统计总记录数

第二条SQL语句,用来进行分页查询,查询指定页码对应 的数据列表。

其实就是将我们编写的SQL语句进行的改造增强,在SQL语句之后拼接上了limit进行分页查询,而由于测试时查询的是第一页,起始索引是0,所以简写为limit ?

而PageHelper在进行分页查询时,会执行上述两条SQL语句,并将查询到的总记录数,与数据列表封装到了 Page<Emp> 对象中,我们再获取查询结果时,只需要调用Page对象的方法就可以获取

注意:

  • PageHelper实现分页查询时,SQL语句的结尾一定一定一定不要加分号(;).。

  • PageHelper只会对紧跟在其后的第一条SQL语句进行分页处理。

条件分页查询

主要是看一下SQL语句怎么写的

XML 复制代码
<!--定义Mapper映射文件的约束和基本结构-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
    <select id="list" resultType="com.itheima.pojo.Emp">
        select e.*, d.name deptName from emp as e left join dept as d on e.dept_id = d.id
        <where>
            <if test="name != null and name != ''">
                e.name like concat('%',#{name},'%')
            </if>
            <if test="gender != null">
                and e.gender = #{gender}
            </if>
            <if test="begin != null and end != null">
                and e.entry_date between #{begin} and #{end}
            </if>
        </where>
    </select>
</mapper>

<if>:判断条件是否成立,如果条件为true,则拼接SQL。

<where>:根据查询条件,来生成where关键字,并会自动去除条件前面多余的and或or

所谓动态SQL,指的就是随着用户的输入或外部的条件的变化而变化的SQL语句

补充:

当我们在测试的时候,页码输入负数,查询是有问题的,查不到对应的数据了

那其实在PageHelper中,我们可以通过合理化参数配置,来解决这个问题。直接在application.yml中,引入如下配置即可:

java 复制代码
pagehelper:
  reasonable: true
  helper-dialect: mysql
相关推荐
http阿拉丁神猫1 小时前
Go语言入门笔记:从基础到开发环境搭建(二)
开发语言·笔记·golang
不会就选b2 小时前
C++补充部分(一)--lambda 表达式
开发语言·c++
Pniubi5 小时前
HashMap的扩容和树化边界
java·开发语言
Mikko75 小时前
用 Java 复刻了高中时在塞班上玩的「熔岩矿车」:纯 Swing、零依赖、没有一张图片,一个 jar 双击就能玩
java·游戏开发·swing
知了学历孙老师5 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
Java爱好狂.5 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
秋饼6 小时前
LLM API密钥动态轮换实战:Spring Vault + Spring AI + 多Provider路由
java·ai·技术分享·后端开发
gCode Teacher 格码致知6 小时前
Pandas教学-17:Series与Dataframe的关系
开发语言·python·pandas
发量惊人的中年网工6 小时前
分公司访问总部ERP慢怎么办?SD-WAN组网的排查与验收要点
服务器·开发语言·php
下页、再停留7 小时前
【C#桌面客户端系列学习-15】生成可视化图表之折线图、柱状图、饼状图
开发语言·c#