任务五我们进行了一个拓展训练,熟练掌握了spring boot集成mybatis时使用xml配置的方式。由于我们这里做的管理系统比较简单,主要是给大家介绍整个项目结构以及流程,所以,后期我们暂时不使用.xml方式,后续将给大家介绍mybatis-plus数据连接方式,将更加集成。
前面我们已经在后端实现了各种数据的增删改查,为项目的后续开发打下来扎实的基础。本次任务,我们就来到激动人心的时刻,实现前后端跨域连接,把我们查询到的数据在前端进行展示,并且我们还将实现分页查询功能。通过本次任务,大家能够:
(1)掌握分页查询SQL原理以及SQL统计语句(统计总记录数);
(2)了解前后端跨域的概念;
(3)后端添加跨域配置,实现前后端跨域;
(4)掌握前端pageNum和pageSize以及分页方法。
一般来说,分页查询核心就是:每页需要显示多少条记录(pageSize),当前查看第几页(pageNum)。
SQL查找语句为:select * from table limit (pageNum-1)*pageSize, pageSize;
我们知道MySQL提供了分页函数limit m,n,但是该函数的用法和需求不一样,所以就需要根据实际情况去改写以满足需求。分析如下:
查询第1条到第10条数据的sql是:select * from table limit 0,10; ->对应我们的需求就是查询第一页的数据:select * from table limit (1-1)*10,10;
查询第10条到第20条数据的sql是:select * from table limit 10,20;
->对应我们的需求就是查询第二页的数据:select * from table limit (2-1)*10,10;
查询第20条到第30条数据的sql是:select * from table limit 20,30;
->对应我们的需求就是查询第三页的数据:select * from table limit (3-1)*10,10;
通过上面的分析,可以归纳得出符合需求的分页SQL伪代码是:select * from table limit (pageNum-1)*pageSize,pageSize。总而言之,我们只需要告诉数据库要从第几行开始拿多少条数据就行了。但是,limit语句不支持计算,因此,需要从外部传参。
在UserMapper接口,继续添加分页查询的方法,代码如下:
@Select("select * from sys_user limit #{pageNum},#{pageSize}")
List selectPage(Integer pageNum, Integer pageSize);
在UserService类,添加selectPage方法,代码如下:
public List selectPage(Integer pageNum, Integer pageSize) {
return userMapper.selectPage(pageNum,pageSize);
}
在UserController类,添加映射方法findPage,代码如下:
//分页查询
//接口路径user/page?pageNum=1&pageSize=10
//RequestParam接受前台传过来的第几页,每页显示数
@GetMapping("/page")
public List findPage(@RequestParam Integer pageNum,@RequestParam Integer pageSize){
pageNum=(pageNum-1)*pageSize;
return userService.selectPage(pageNum,pageSize);
}
分页显示的时候通常需要获取总记录数。
在UserMapper接口,添加查询记录总数的方法selectTotal。代码如下:
@Select("select count(*) from sys_user")
Integer selectTotal();
修改UserController类的findPage,返回总条数及当前需要页的数据,代码如下:
@GetMapping("/page")
public Map findPage(@RequestParam Integer pageNum,@RequestParam Integer pageSize){
pageNum=(pageNum-1)*pageSize;
List data=userService.selectPage(pageNum,pageSize);
Integer total=userMapper.selectTotal();
Map res=new HashMap<>();
res.put("data",data);
res.put("total",total);
return res;
}
说明: 这里因为逻辑需求非常简单,所以就没有再使用UserService接口了。
代码如下:
created(){
//请求分页查询数据
fetch("http://localhost:8084/user/page?pageNum=2&pageSize=2").then(res=>res.json()).then(res=>{
//查看跨域返回数据
console.log(res)
})
}
此时运行后,F12浏览器打开开发者工具,会发现下面的错误:
注意: 这个跨域错误提示我们没有做允许跨域的设置。
跨域设置可以采用前端配置方式,也可以采用后端配置方式,这里采用后端配置。
新建config包,然后新建一个CorsConfig类,进行跨域设置,代码如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
// 当前跨域请求最大有效时长。这里默认1天
private static final long MAX_AGE = 24 * 60 * 60;
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
corsConfiguration.setMaxAge(MAX_AGE);
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
设置跨域后,如果跨域不起作用,建议重新运行一下项目。尤其是使用了热部署的同学,强烈建议停止原先的运行,重新启动。这时候就不会再报跨域的错误了。
解决跨域问题后,我们从以下几个地方修改前端页面。
(1)表格字段与数据表字段保持一致;
(2)参数pageNum和pageSize设置初始值为1,5,从第1页开始每页5条记录;
(3)应用Element中分页插件的@size-change="handleSizeChange"
, @current-change="handleCurrentChange"
两个方法handleSizeChange(val)
和 handleCurrentChange(val)
分别获取每一页显示的条目数、当前第几页,然后点击不同页码时重新加载数据。
home组件完整代码如下:
王小虎
个人信息
退出
搜索
新增
批量删除
导入
导出
编辑
删除
供大家在完善页面时进行参考。
这时候会发现总条目数,当前页共显示5条记录。
开发者工具中可以查看数据
本次任务我们终于做到了最有获得感的前后端数据跨域连接。实现了分页查询。
本次任务,主要完成并掌握以下内容:
(1)MySQL分页查询原理;
(2)通过后端CorsConfig实现跨域设置;
(3)前端分页插件使用,分页器应用。