SpringBoot整合mybatis-plus实现分页查询(建议收藏)
Posted 慕言要努力
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot整合mybatis-plus实现分页查询(建议收藏)相关的知识,希望对你有一定的参考价值。
一、前言
最近学习了SpringBoot分页查询的两种写法,一种是手动实现,另一种是使用框架实现。现在我将具体的实现流程分享一下。
二、手动实现分页查询
先复习一下,SQL中的limit关键字,下面一行sql语句的意思是从第二个数据开始查,查询出两条数据
SELECT * FROM map limit 1,2;
使用limit前一个参数pageNum是从第几个数据开始查,后一个参数pageSize是查询多少条数据,注意数据库查询pageNum=0代表第一个数据。
那么在Springboot中该如何写呢?
三、了解@RequestParam
1.什么是@RequestParam
- @RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
2.语法
语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
value:参数名
required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
3.测试环境
环境:jdk1.8 Tomcat8.5 idea2018 manven父工程子模块
步骤:
1、创建web工程、引入依赖
2、配置SpringMvc入口文件 --DispatcherServlet--为总调度、web.xml里配置
3、创建Springmvc.xml文件--理解为:适配器(这里不需要自已指定适配、springmvc会自动指定)--视图解析器
4、创建 业务处理器 Controller类
5、测试
四、了解QueryWrapper
1.QueryWrapper是什么?
QueryWrapper就是在使用Mybatis-plus中真实用到的一种技术,也叫作构造器,能简化sql的操作。
2.常用方法总结
代码如下(示例):我要查询姓名、班级、年龄符合前端传过来参数的数据并进行排序。
@GetMapping("/list")
public TableDataInfo list(Student student)
LambdaQueryWrapper<Student> lqw = new LambdaQueryWrapper<Student>();
lqw.eq(Student::getName, student.getName());
lqw.like(Student::getClass,student.getClass());
lqw.between("age",student.getAge1(),student.getAge2());
lqw.orderByAsc("age");
List<Student> list = studentService.list(lqw);
以上代码对应的sql为:
select * from student where name = '?' and class like '%?%' and age between '?' and '?' order by '?' asc
由此可以看出,QueryWrapper其实可以理解成一个放查询条件的盒子,我们把查询条件放在里面,他就会自动按照对应的条件进行查询数据。
根据不同的查询要求,有不同的用法,常用到的比如:eq、like、and、or、isNull、isNotNull、ne、likeRight、between等;使用方法及说明见下图。
2、多表操作
//Controller
@GetMapping("/listAndClass")
public TableDataInfo listAndClass(Student student)
QueryWrapper<Student > qw = new QueryWrapper<Student >();
if(StringUtils.isNotBlank(student.getName()))
qw.eq("s.name",student.getName());
if(StringUtils.isNotBlank(student.getClassName()))
qw.like("c.name",student.getClassName());
startPage();
List<Student > list = studentService.listAndClass(qw);
return getDataTable(list);
//Service
List<Student> listAndClass(QueryWrapper<Student> qw);
//Service impl
@Override
public List<Student> listAndClass(QueryWrapper<Student> qw)
return this.getBaseMapper().listAndClass(qw);
//Mapper
@Select("select s.*,c.name from student s left join class c on s.id = c.student_id "+
"$ew.customSqlSegment")
List<YwSpaqjgDj> listAndClass(@Param(Constants.WRAPPER) QueryWrapper<Student> qw);
五.SpringBoot实现分页查询
1.创建UserController
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.Constants;
import com.example.demo.common.Result;
import com.example.demo.controller.dto.UserDTO;
import com.example.demo.entity.User;
import com.example.demo.service.IUserService;
import com.example.demo.utils.TokenUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController
@Resource
private IUserService userService;
@PostMapping("/login")
public Result login(@RequestBody UserDTO userDTO)
String username = userDTO.getUsername();
String password = userDTO.getPassword();
if (StrUtil.isBlank(username) || StrUtil.isBlank(password))
return Result.error(Constants.CODE_400,"参数错误");
UserDTO dto = userService.login(userDTO);
return Result.success(dto);
@PostMapping("/register")
public Result register(@RequestBody UserDTO userDTO)
String username = userDTO.getUsername();
String password = userDTO.getPassword();
if (StrUtil.isBlank(username) || StrUtil.isBlank(password))
return Result.error(Constants.CODE_400,"参数错误");
return Result.success(userService.register(userDTO));
//新增或者更新
@PostMapping
public Result save(@RequestBody User user)
String username = user.getUsername();
if (StrUtil.isBlank(username))
return Result.error(Constants.CODE_400, "参数错误");
if (user.getId() != null)
user.setPassword(null);
else
user.setNickname(user.getUsername());
if (user.getPassword() == null)
user.setPassword("123456");
return Result.success(userService.saveOrUpdate(user));
//删除
@DeleteMapping("/id")
public Result delete(@PathVariable Integer id)
return Result.success(userService.removeById(id));
@PostMapping("/del/batch")
public Result deleteBatch(@RequestBody List<Integer> ids) //批量删除
return Result.success(userService.removeByIds(ids));
@GetMapping("/id")
public Result findOne(@PathVariable Integer id)
return Result.success(userService.getById(id));
@GetMapping("/username/username")
public Result findOne(@PathVariable String username)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", username);
return Result.success(userService.getOne(queryWrapper));
并在Controller里面写好page接口
@GetMapping("/page")
public Result findPage(@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam(defaultValue = "") String username)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id");
if (!"".equals(username))
queryWrapper.like("username", username);
return Result.success(userService.page(new Page<>(pageNum, pageSize), queryWrapper));
不难看出我们是根据数据库的id进行查询出数据库的数据
queryWrapper.orderByDesc("id")
六、了解equals
1.什么是equals
equals():equals是Object中的方法,用于检测一个对象是否等于另一个对象,在Object中equals方法实际"ruturn (this==obj)",用到的还是"==",说明如果对象不重写equals方法,实际该对象的equals和"=="作用是一样的,都是比较的地址值(因为"=="比较的就是地址值),但是大部分类都会重写父类的equals方法,用来检测两个对象是否相等,即两个对象的内容是否相等,例如String就重写了equals方法,用来比较两个字符串内容是否相同。看以下代码:
public static void main(String[] args)
Object o = new Object();
Object o1 = o;
Object o2 = o;
System.out.println(o3.equals(o2));
代码输出:true
所以我们是使用 equals来确定我们查询数据的对象,所以我们这里选择使用username来查询数据库里面的具体数据
if (!"".equals(username))
queryWrapper.like("username", username);
七、前端使用
1.前端技术栈
对于前端,我们使用的是Vue+Element来进行功能实现,对于跨域的处理我使用的是axios进行处理,并且对axios进行了封装,具体步骤请查看:解决SpringBoot和前端Vue的跨域问题_慕言要努力的博客-CSDN博客
2.组件使用
我选用的是Element官网的组件来进行数据渲染
我们进行组件使用,并且设置分页的数据数量,数据可分为一页5条、10条以及15条
<div style="padding: 10px 0">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[ 5, 10, 15]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
3.数据渲染
我们默认查询处理的数据是0,设置页数为一页,一页为5条数据
data()
return
tableData: [],
total: 0,
pageNum: 1,
pageSize: 5,
username: "",
form: ,
dialogFormVisible: false,
multipleSelection: [],
headerBg: "headerBg",
roles: []
最后进行数据请求,请求后台写好的page接口
methods:
load: function ()
this.request.get("/user/page",
params:
pageNum: this.pageNum,
pageSize: this.pageSize,
username: this.username,
).then(res =>
this.tableData = res.data.records
this.total = res.data.total
)
this.request.get("/role").then(res =>
this.roles = res.data
)
八、功能展示
最后附上前端完整代码
<template>
<div>
<div style="margin: 10px 0">
<el-input style="width: 200px; margin-left: 10px" placeholder="请输入用户名" clearable suffix-icon="el-icon-user" v-model="username" ></el-input>
<el-button class="ml-5" type="primary" @click="load"><i class="el-icon-search" />搜索</el-button>
<el-button type="warning" @click="reset"><i class="el-icon-refresh" />刷新</el-button>
</div>
<div style="margin: 10px 0">
<el-button type="primary" @click="handleAdd" class="ml-10"><i class="el-icon-circle-plus-outline" />新增</el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确认'
cancel-button-text='取消'
icon="el-icon-info"
icon-color="red"
title="确定批量删除这些信息吗?"
@confirm="delBatch">
<el-button type="danger" slot="reference" ><i class="el-icon-remove-outline" />删除</el-button>
</el-popconfirm>
<el-upload action="http://localhost:9090/user/import" :show-file-list="false" accept=".xlsx"
:on-success="handleExcelImportSuccess" style="display: inline-block">
<el-button type="primary" class="ml-5"><i class="el-icon-upload"></i>导入</el-button>
</el-upload>
<el-button type="primary" class="ml-5" @click="exp"><i class="el-icon-download" />导出</el-button>
</div>
<el-table :data="tableData" border stripe :header-cell-class-name="headerBg"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="username" label="用户名" ></el-table-column>
<el-table-column prop="nickname" label="昵称" ></el-table-column>
<el-table-column prop="email" label="邮箱" ></el-table-column>
<el-table-column prop="phone" label="联系方式" ></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
<!-- <el-table-column prop="role" label="身份"></el-table-column>-->
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="success" @click="handleEdit(scope.row)"><i class="el-icon-edit-outline" />编辑</el-button>
</template>
</el-table-column>
</el-table>
<div style="padding: 10px 0">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[ 5, 10, 15]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
<el-dialog title="用户信息" :visible.sync="dialogFormVisible" width="30%">
<el-form :model="form" label-width="100px" size="small">
<el-form-item label="用户名" >
<el-input v-model="form.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="昵称" >
<el-input v-model="form.nickname" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱" >
<el-input v-model="form.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="联系方式" >
<el-input v-model="form.phone" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="地址" >
<el-input v-model="form.address" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default
name: "User",
data()
return
tableData: [],
total: 0,
pageNum: 1,
pageSize: 5,
username: "",
form: ,
dialogFormVisible: false,
multipleSelection: [],
headerBg: "headerBg",
roles: []
,
created()
this.load()
,
methods:
load: function ()
this.request.get("/user/page",
params:
pageNum: this.pageNum,
pageSize: this.pageSize,
username: this.username,
).then(res =>
this.tableData = res.data.records
this.total = res.data.total
)
this.request.get("/role").then(res =>
this.roles = res.data
)
,
home()
this.$router.push("/")
,
save()
this.request.post("/user", this.form).then(res =>
if (res.code === '200')
this.$message.success("保存成功")
this.dialogFormVisible = false
this.load()
else
this.$message.error("保存失败")
)
,
handleAdd()
this.dialogFormVisible = true
this.form =
,
handleEdit(row)
this.form = row
this.dialogFormVisible = true
,
handleSelectionChange(val)
console.log(val)
this.multipleSelection = val;
,
exp()
window.open("http://localhost:9090/user/export")
,
handleExcelImportSuccess()
this.$message.success("文件导入成功")
this.load()
,
delBatch()
let ids = this.multipleSelection.map(v => v.id) //[, , ] => [1,2,3]
this.request.post("/user/del/batch", ids).then(res =>
if (res.code === '200')
this.$message.success("删除用户成功")
this.load()
else
this.$message.error("删除用户失败")
)
,
reset()
this.username = ""
this.load()
,
handleSizeChange(pageSize)
console.log(pageSize)
this.pageSize = pageSize
this.load()
,
handleCurrentChange(pageNum)
console.log(pageNum)
this.pageNum = pageNum
this.load()
,
</script>
<style>
.headerBg
background: #eee!important;
</style>
⛵小结
以上就是对SpringBoot整合mybatis-plus实现分页查询简单的概述,现在我们的项目就更加的趋于完美了,也提升了我们对于编程的能力和思维!
如果这篇文章有帮助到你,希望可以给作者点个赞👍,创作不易,如果有对后端技术、前端领域感兴趣的,也欢迎关注 ,我将会给你带来巨大的收获与惊喜💝💝💝!
大三东软暑期实训-springboot整合篇
1.整合mybatis
pom.xml:
<!--
springboot整合mybatis 框架启动器
-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
.yml
spring:
datasource:
url: jdbc:mysql://localhost:3307/db_ldk?characterEncoding=utf8
password: 1234
username: root
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mappers/*.xml
2.整合德鲁伊连接池
pom.xml
<!--Druid 数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
.yml:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource #使用druid连接池
url: jdbc:mysql://localhost:3306/store?characterEncoding=utf8
password: root
username: root
driver-class-name: com.mysql.jdbc.Driver
druid: #配置 Druid 的相关参数
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000 # 配置获取连接等待超时的时间
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存时间
validation-query: SELECT 1 #SELECT 1 FROM sys_user
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true # 打开 PSCache,并且指定每个连接上 PSCache 的大小
max-pool-prepared-statement-per-connection-size: 20
#filters: stat,wall,log4j # 配置监控统计拦截的 Filter,去掉后监控界面 SQL 无法统计,wall 用于防火墙
web-stat-filter: # 配置 DruidStatFilter
enabled: true
url-pattern: /*
exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
stat-view-servlet: # 配置 DruidStatViewServlet
url-pattern: /druid/*
# IP 白名单,没有配置或者为空,则允许所有访问
allow: 127.0.0.1
# IP 黑名单,若白名单也存在,则优先使用
deny: 192.168.31.253
# 禁用 HTML 中 Reset All 按钮
reset-enable: false
# 登录用户名/密码
login-username: root
login-password: root
3.整合logback 日志
在resources下面创建logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<property name="LOG_FILE_NAME_PATTERN" value="logs/auth.%d{yyyy-MM-dd}.%i.log"/>
<!-- 日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%c){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<property name="FILE_LOG_PATTERN"
value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %c : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到文件-->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_NAME_PATTERN}</fileNamePattern>
<!-- 日志保留天数 -->
<maxHistory>366</maxHistory>
<!-- 日志文件上限大小,达到指定大小后删除旧的日志文件 -->
<totalSizeCap>2GB</totalSizeCap>
<!-- 每个日志文件的最大值 -->
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- (多环境配置日志级别)根据不同的环境设置不同的日志输出级别 -->
<springProfile name="default,local">
<root level="info">
<appender-ref ref="console"/>
</root>
<logger name="com.zhl" level="debug"/>
</springProfile>
<springProfile name="dev,test">
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
<logger name="com.zhl" level="debug"/>
</springProfile>
<springProfile name="product,pre">
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
<logger name="com.zhl" level="debug"/>
</springProfile>
</configuration>
4.整合jsp
pom.xml:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope><!--去除打包-->
</dependency>
5.整合mybatis-plus
注释掉mybatis-spring-boot-starter
的依赖
<!--spring整合mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
.yml
#mybatis-plus的配置
mybatis-plus:
type-aliases-package: edu.xlh.springboot0624_v2.pojo #配置实体别名
mapper-locations: classpath:mappers/*.xml
configuration:
map-underscore-to-camel-case: true #自动开启驼峰规则映射
6.配置视图解析器:
mvc:
view:
prefix: /WEB-INF/
suffix: .jsp
7.
与jsp不共存
pom.xml
<!--springboot整合thymeleaf模板技术-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
/templates/.html
8.热部署
pom.xml
<!--支持热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
ctrl+alt+shift+/
9.项目打包
SpringBoot项目在打包的时候,需要考虑一个问题就是,项目是否有jsp页面。如果有jsp页面需要将项目打成war包。如果没有jsp的可以将项目打成jar包(html/thymeleaf)
D盘,java -jar 后面名字打几个再Tab补全
java -jar springboot0624_v2-0.0.1-SNAPSHOT.jar
以上是关于SpringBoot整合mybatis-plus实现分页查询(建议收藏)的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot 整合 MyBatis-Plus 入门体验