Vue+SpringBoot实现员工管理系统
在SpringBoot
整合MyBatis-plus
实现分页查询
1.创建一个配置类MyBatisPlusConfig
配置类的作用是创建Mybatis-plus
的拦截器
package com.yurui.manage_system_springboot.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author YurUi
* @Version 1.0
*/
@Configuration
public class MyBatisPlusConfig {
// 配置mybatis-plus拦截器
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 创建分页拦截器,并指定数据库类型,如使用是mysql
PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
// 添加分页拦截器
interceptor.addInnerInterceptor(innerInterceptor);
return interceptor;
}
}
2.Controller
控制器方法
package com.yurui.manage_system_springboot.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yurui.manage_system_springboot.pojo.User;
import com.yurui.manage_system_springboot.pojo.vo.UserVo;
import com.yurui.manage_system_springboot.service.UserService;
import com.yurui.manage_system_springboot.utils.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Author YurUi
* @Version 1.0
*/
@RestController
@RequestMapping("/admin/system/user")
@Api(tags = "系统接口")
public class SystemController {
@Autowired
private UserService userService;
// 分页查询
@GetMapping("/pageFindUser/{pageNum}/{pageSize}")
@ApiOperation("分页查询")
public JsonResult pageFindUser(
@ApiParam(value = "页码数",name = "pageNum",required = true)
@PathVariable("pageNum") Long pageNum,
@ApiParam(value = "每页大小",name = "pageSize",required = true)
@PathVariable("pageSize")Long pageSize,
@ApiParam(value = "查询对象",name = "UserVo",required = false)
UserVo vo
){
// 设置分页参数
Page<User> page = new Page<>(pageNum,pageSize);
// 设置service层
IPage<User> userIPage = userService.selectPageVo(page,vo);
// 响应数据
return JsonResult.ok(userIPage);
}
}
UserVo
类用于模糊查询的条件
package com.yurui.manage_system_springboot.pojo.vo;
import lombok.Data;
import lombok.ToString;
/**
* @Author YurUi
* @Version 1.0
*/
// 用户模糊查询条件
@Data
@ToString
public class UserVo {
private String username;
private String email;
private String address;
}
3.Service
接口
package com.yurui.manage_system_springboot.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yurui.manage_system_springboot.pojo.User;
import com.yurui.manage_system_springboot.pojo.vo.UserVo;
import java.util.List;
/**
* @Author YurUi
* @Version 1.0
*/
public interface UserService extends IService<User> {
// 分页查询
IPage<User> selectPageVo(Page<User> page, UserVo vo);
}
接口实现类:
package com.yurui.manage_system_springboot.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yurui.manage_system_springboot.mapper.UserMapper;
import com.yurui.manage_system_springboot.pojo.User;
import com.yurui.manage_system_springboot.pojo.vo.UserVo;
import com.yurui.manage_system_springboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* @Author YurUi
* @Version 1.0
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
@Autowired
private UserMapper userMapper;
// 分页查询
@Override
public IPage<User> selectPageVo(Page<User> page, UserVo vo) {
IPage<User> p = userMapper.selectPaveVo(page,vo);
return p;
}
}
4.Mapper
接口
package com.yurui.manage_system_springboot.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yurui.manage_system_springboot.pojo.User;
import com.yurui.manage_system_springboot.pojo.vo.UserVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Author YurUi
* @Version 1.0
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 分页查询
IPage<User> selectPaveVo(Page<User> page, UserVo vo);
}
xml
文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yurui.manage_system_springboot.mapper.UserMapper">
<resultMap id="UserEntityMap" type="user">
<id column="id" property="id"/>
<result column="avatar_url" property="avatarUrl"/>
<result column="created_time" property="createdTime"/>
<result column="modified_time" property="modifiedTime"/>
<result column="created_user" property="createdUser"/>
<result column="modified_user" property="modifiedUser"/>
<result column="is_delete" property="isDelete"/>
</resultMap>
<select id="getAllUser" resultMap="UserEntityMap">
select * from sys_user where is_delete = 0
</select>
<!-- selectPaveVo 分页查询 -->
<select id="selectPaveVo" resultMap="UserEntityMap">
select * from sys_user
<where>
<if test="vo.username!=null and vo.username!=''">
username like "%"#{vo.username}"%"
</if>
<if test="vo.email!=null and vo.email!=''">
and email like "%"#{vo.email}"%"
</if>
<if test="vo.address!=null and vo.address!=''">
and address like "%"#{vo.address}"%"
</if>
and is_delete = 0
</where>
ORDER BY id DESC
</select>
</mapper>
5.启动项目测试
测试是整合了Knife4j
工具, (244条消息) SpringBoot整合Swagger2_昱晟168的博客-CSDN博客
http://localhost:8888/doc.html
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d4SEbevU-1670817674718)(D:\typora笔记\vue+SpringBoot后台管理系统\img\1669110905717.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J7wu7ndT-1670817674719)(D:\typora笔记\vue+SpringBoot后台管理系统\img\1669110889448.png)]
6.解决跨域问题
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);
}
}
7.封装axios
第一步:创建request.js
文件,用于封装axios
import axios from 'axios'
// create an axios instance
const service = axios.create({
baseURL:'http://localhost:8888/admin/system',
timeout: 5000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
console.log(config)
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
const res = response.data
console.log(res);
return res
},
error => {
console.log('err' + error) // for debug
return Promise.reject(error)
}
)
export default service
第二步:创建sysUser.js
统一管理user
请求
import request from '@/api/request';
// 用户接口
export default{
// 条件分页查询
pageFindUser(pageNum,pageSize,searchObj){
return request({
url:`/user/pageFindUser/${
pageNum}/${
pageSize}`,
method:'get',
params:searchObj
})
}
}
8.响应前端数据
<template>
<el-container style="min-height: 100vh">
<el-aside :width="sideWidth + 'px'" style="background-color: rgb(238, 241, 246); box-shadow: 2px 0 6px rgb(0 21 41 / 35%);">
<el-menu :default-openeds="['1', '3']" style="min-height: 100%; overflow-x: hidden"
background-color="rgb(48, 65, 86)"
text-color="#fff"
active-text-color="#ffd04b"
:collapse-transition="false"
:collapse="isCollapse"
>
<div style="height: 60px; line-height: 60px; text-align: center">
<img src="../assets/logo.png" alt="" style="width: 20px; position: relative; top: 5px; margin-right: 5px">
<b style="color: white" v-show="logoTextShow">后台管理系统</b>
</div>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-message"></i>
<span slot="title">导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="2-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-setting"></i>
<span slot="title">导航三</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="3-1">选项1</el-menu-item>
<el-menu-item index="3-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="3-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="3-4">
<template slot="title">选项4</template>
<el-menu-item index="3-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="font-size: 12px; border-bottom: 1px solid #ccc; line-height: 60px; display: flex">
<div style="flex: 1; font-size: 20px">
<span :class="collapseBtnClass" style="cursor: pointer" @click="collapse"></span>
</div>
<el-dropdown style="width: 70px; cursor: pointer">
<span>YURUI</span><i class="el-icon-caret-bottom" style="margin-left: 5px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-header>
<el-main>
<!-- 活动 -->
<div style="margin-bottom: 30px">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- 搜索相关操作 -->
<div>
<el-input
style="width:250px;margin: 5px 5px 5px 0px"
placeholder="请输入名称"
suffix-icon="el-icon-search"
clearable
v-model="sysUserVo.username"
>
</el-input>
<el-input
style="width:250px;margin: 5px 5px 5px 0px"
placeholder="请输入邮箱"
suffix-icon="el-icon-s-comment"
clearable
v-model="sysUserVo.email"
>
</el-input>
<el-input
style="width:250px;margin: 5px 5px 5px 0px"
placeholder="请输入地址"
suffix-icon="el-icon-add-location"
clearable
v-model="sysUserVo.address"
>
</el-input>
<el-button type="primary" style="width:80px" @click="searchPage">搜索</el-button>
</div>
<div style="margin: 10px 0">
<el-button type="primary">新增 <i class="el-icon-circle-plus-outline"></i></el-button>
<el-button type="danger">批量删除 <i class="el-icon-remove-outline"></i></el-button>
<el-button type="primary">导入 <i class="el-icon-bottom"></i></el-button>
<el-button type="primary">导出 <i class="el-icon-top"></i></el-button>
</div>
<el-table :data="tableData"
stripe
>
<el-table-column prop="id" label="ID" width="100"></el-table-column>
<el-table-column prop="username" label="姓名" width="180">
</el-table-column>
<el-table-column prop="nickname" label="昵称" width="150">
</el-table-column>
<el-table-column prop="email" label="邮箱" width="180"></el-table-column>
<el-table-column prop="phone" label="电话" width="180"></el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
<el-table-column label="操作" width="250" align="center">
<template slot-scope="scope">
<el-button type="success">编辑 <i class="el-icon-edit"></i></el-button>
<el-button type="danger">删除 <i class="el-icon-remove-outline"></i></el-button>
</template>
</el-table-column>
</el-table>
<div style="padding:10px 0px">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[2, 5, 15, 50]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</el-main>
</el-container>
</el-container>
</template>
<script>
import api from '@/api/user/sysUser';
export default {
name: 'Home',
data:function(){
return{
tableData:[],
total:0,
collapseBtnClass: 'el-icon-s-fold',
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
pageSize:2,//每页显示大小
pageNum:1,//当前页
sysUserVo:{},//用户封装模糊查询的条件
}
},
created(){
this.fetchData();
},
methods: {
// 搜索处理
searchPage(){
this.fetchData();
console.log(this.sysUserVo)
},
fetchData(pageNum=1){
api.pageFindUser(this.pageNum,this.pageSize,this.sysUserVo)
.then((value)=>{
console.log(this.sysUserVo)
this.tableData = value.data.records;
this.total = value.data.total;
})
},
collapse() { // 点击收缩按钮触发
this.isCollapse = !this.isCollapse
if (this.isCollapse) { // 收缩
this.sideWidth = 64
this.collapseBtnClass = 'el-icon-s-unfold'
this.logoTextShow = false
} else { // 展开
this.sideWidth = 200
this.collapseBtnClass = 'el-icon-s-fold'
this.logoTextShow = true
}
},
// 每页显示大小
handleSizeChange(pageSize){
this.pageSize = pageSize;
this.fetchData();
},
// 当前是第几页
handleCurrentChange(pageNum){
this.pageNum = pageNum;
this.fetchData();
}
}
}
</script>
完全使用mybatis-plus
来实现分页
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yurui.manage_system_springboot.pojo.User;
import com.yurui.manage_system_springboot.pojo.vo.UserVo;
import com.yurui.manage_system_springboot.service.UserService;
import com.yurui.manage_system_springboot.utils.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Author YurUi
* @Version 1.0
*/
@RestController
@RequestMapping("/admin/system/user")
@Api(tags = "系统接口")
public class SystemController {
@Autowired
private UserService userService;
@GetMapping("/pagePlus/{pageNum}/{pageSize}")
@ApiOperation("分页查询")
public JsonResult pagePlus(
@ApiParam(value = "页码数",name = "pageNum",required = true)
@PathVariable("pageNum") Long pageNum,
@ApiParam(value = "每页大小",name = "pageSize",required = true)
@PathVariable("pageSize")Long pageSize,
@ApiParam(value = "查询对象",name = "UserVo",required = false)
UserVo vo
){
// 第一步:设置page对象
Page<User> page = new Page<>(pageNum,pageSize);
// 第二步:封装分页条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 第三步:必须先判断分页的条件不为空时,才能拼接该条件【注意】
if (vo.getUsername()!=null){
System.out.println(vo.getUsername());
queryWrapper.like(StringUtils.isNotBlank(vo.getUsername()),"username",vo.getUsername());
}
if (vo.getEmail()!=null){
queryWrapper.like(StringUtils.isNotBlank(vo.getEmail()),"email",vo.getEmail());
}
if (vo.getAddress()!=null){
queryWrapper.like(StringUtils.isNotBlank(vo.getAddress()),"address",vo.getAddress());
}
Page<User> userPage = userService.page(page, queryWrapper);
return JsonResult.ok(userPage);
}
}