SpringBoot3.0(Mybatis)+Vue3.0(ElementPlus)快速实现分页查询功能

1、Vue3.0前端代码

1.1、前端代码书写

注:此页面设计el-table、el-pagination、el-dialog、el-form及一些其他的组件,可参考ElementPlus官网(一个 Vue 3 UI 框架 | Element Plus)文档详细使用。

<template>
  <div style="margin-bottom: 15px">
      <el-input v-model="params.name" style="width: 240px" placeholder="请输入用户名" />
      <el-input v-model="params.phone" style="width: 240px; margin-left: 5px" placeholder="请输入手机号" />
      <el-button type="warning" style="margin-left: 10px" @click="findBySearch">查询</el-button>
      <el-button type="primary" style="margin-left: 10px" @click="resetInput">清空</el-button>
      <el-button type="primary" style="margin-left: 10px" @click="addUserInfo">新增</el-button>
  </div>
  <div>
      <el-table :data="tableData" style="width: 100%">
          <el-table-column prop="name" label="姓名" />
          <el-table-column prop="sex" label="性别" />
          <el-table-column prop="age" label="年龄" />
          <el-table-column prop="phone" label="手机号" />
          <el-table-column label="操作">
              <template #default="scope">
                  <el-button @click="editUserInfo(scope.row)" type="primary">编辑</el-button>
                  <el-popconfirm title="你确定要删除吗?" @confirm="userInfoDelete(scope.row)" confirm-button-text="确定"
                      cancel-button-text="取消" width="300px">
                      <template #reference>
                          <el-button type="danger">删除</el-button>
                      </template>
                  </el-popconfirm>
              </template>
          </el-table-column>
      </el-table>
  </div>
  <div class="demo-pagination-block">
      <el-pagination v-model:current-page="params.currentPage" v-model:page-size="params.pageSize"
          :page-sizes="[5, 10, 15, 20]" layout="total, sizes, prev, pager, next, jumper" :total="total"
          @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  </div>

  <div>
      <!-- 对话框 -->
      <el-dialog v-model="dialogVisible" title="请填写用户信息" width="500">
          <el-form ref="addFormRef" style="max-width: 600px" :model="addForm" :rules="rules" label-width="120px"
              class="demo-ruleForm" status-icon>
              <el-form-item label="姓名" prop="name">
                  <el-input v-model="addForm.name" />
              </el-form-item>
              <el-form-item label="性别" prop="sex">
                  <el-radio v-model="addForm.sex" label="男">男</el-radio>
                  <el-radio v-model="addForm.sex" label="女">女</el-radio>
              </el-form-item>
              <el-form-item label="年龄" prop="age">
                  <el-input v-model="addForm.age" />
              </el-form-item>
              <el-form-item label="手机" prop="phone">
                  <el-input v-model="addForm.phone" />
              </el-form-item>
              <el-form-item label="角色" prop="typeId">
                  <el-select v-model="addForm.role" placeholder="请选择角色类型" style="width: 90%;">
                      <el-option label="教师" value="teacher"></el-option>
                      <el-option label="用户" value="user"></el-option>
                  </el-select>
              </el-form-item>
          </el-form>

          <template #footer>
              <div class="dialog-footer">
                  <el-button @click="dialogVisible = false">取消</el-button>
                  <el-button type="primary" @click="confirmAdd()">
                      确定
                  </el-button>
              </div>
          </template>
      </el-dialog>
  </div>

</template>

<script setup>
import { onMounted, ref, reactive } from "vue";
import { ElMessage } from 'element-plus'
import request from "../../utils/request";

const params = ref({
  name: "",
  phone: "",
  currentPage: 1,
  pageSize: 5,
});
const tableData = ref([]);

onMounted(() => {
  findBySearch();
});


const findBySearch = async () => {
  var res = await request.get(`http://localhost:8080/user/search`, { params: params.value });
  // console.log(res);
  tableData.value = res.data.list;

  total.value = res.data.total;
};
const resetInput = () => {
  params.value.name = "";
  params.value.phone = "";
  findBySearch()
};

const total = ref(0);
const handleSizeChange = async (pageSize) => {
  params.value.pageSize = pageSize;
  await findBySearch();
};
const handleCurrentChange = async (currentPage) => {
  params.value.currentPage = currentPage;
  await findBySearch();
};


const dialogVisible = ref(false)
const addUserInfo = () => {
  addForm.name = ""
  addForm.sex = "男"
  addForm.age = ""
  addForm.phone = ""
  addForm.role = ""
  dialogVisible.value = true
}
const addFormRef = ref()
const addForm = reactive({
  name: "",
  sex: "男",
  age: "",
  phone: "",
  role: ''
})
const rules = reactive({
  name: [
      { required: true, message: '请输入姓名', trigger: 'blur' },
  ],
  sex: [
      { required: true, message: '请选择性别', trigger: 'blur' },
  ],
  age: [
      { required: true, message: '请输入年龄大小', trigger: 'blur' },
  ],
  phone: [
      { required: true, message: '请填写一下手机号', trigger: 'blur' },
  ]
})
const confirmAdd = () => {
  addFormRef.value.validate(async (valid) => {
      if (valid) {
          dialogVisible.value = false
          if (addForm.id) {
              await request.post(`更新接口`, addForm)
              ElMessage({
                  message: '更新成功,请稍后',
                  type: 'success',
              })
          } else {
              let res = await request.post(`新增接口`, addForm)
              console.log(res);
              if (res.code === "200") {
                  ElMessage({
                      message: "添加成功,请稍后",
                      type: 'success',
                  })
              } else {
                  ElMessage.error(res.message)
              }
          }
          await findBySearch()

      }
  })
}

// 编辑
const editUserInfo = (rowObj) => {
  addForm.name = rowObj.name
  addForm.sex = rowObj.sex
  addForm.age = rowObj.age
  addForm.phone = rowObj.phone
  addForm.id = rowObj.id
  addForm.role = rowObj.role
  dialogVisible.value = true
}
const userInfoDelete = async ({ id }) => {
    await request.delete(`删除接口`)

    await findBySearch()
}

</script>


<style lang="scss" scoped>
.demo-pagination-block {
  margin-top: 15px;
  margin-right: 10px;
}

.el-pagination {
  margin-left: 30%;
}
</style>

1.2、axios封装使用

import axios from 'axios'

const request=axios.create({
  baseURL: '设置地址',
  timeout: 5000 
})

// 发出请求之前
request.interceptors.request.use(function (config) {
    // 请求头设置
    config.headers['Content-Type']='application/json;charset=utf-8'
    
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// 处理then和catch之前
request.interceptors.response.use(function (response) {
    // 统一判断是否存在token,存储
    let res=response.data
    if(typeof res==='string'){
        res=res?JSON.parse(res):res
    }

    return res;
  }, function (error) {
    console.log('error:'+error);
    return Promise.reject(error);
  });

  export default request

注:github上有关于axios的详细文档,可作为自己书写的代码的参考文档(https://github.com/axios/axios)

2、SpringBoot3.0后端代码

2.1、导入所需依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis依赖 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>
<!-- mysql依赖 -->
<dependency>
     <groupId>com.mysql</groupId>
     <artifactId>mysql-connector-j</artifactId>
      <scope>runtime</scope>
</dependency>
<!-- get、set依赖 -->
<dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <optional>true</optional>
</dependency>
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
</dependency>
<dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter-test</artifactId>
      <version>3.0.3</version>
      <scope>test</scope>
</dependency>

<!-- mybatis分页查询插件 -->
<dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>1.4.6</version>
</dependency>
<!-- 综合一些简单的查询语句,可直接使用 -->
<dependency>
      <groupId>tk.mybatis</groupId>
      <artifactId>mapper</artifactId>
      <version>4.1.5</version>
</dependency>

2.2、application.yml

server:
  port: 8080

spring:
  main:
    allow-circular-references: true    # 解决循环依赖问题
  application:
    name: demo
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/back_management
    username: root
    password: 123456

mybatis:   # mybatis配置(配置位置)
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.example.demo.entity
  configuration:
    map-underscore-to-camel-case: true

2.3、定义统一的数据返回类型

@Data
public class Result {

    private static final String SUCCESS="200";
    private static final String ERROR="404";

    private String code;
    private String message;
    private Object data;

    public static Result success(){
        Result result = new Result();
        result.setCode(SUCCESS);
        return result;
    }

    public static Result success(Object data){
        Result result = new Result();
        result.setCode(SUCCESS);
        result.setData(data);
        return result;
    }
    public static Result error(String message){
        Result result = new Result();
        result.setCode(ERROR);
        result.setMessage(message);
        return result;
    }
}

2.4、UserController类

@CrossOrigin      // 简单的解决跨域问题
@RestController   //接口的入口
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;


    @GetMapping("/search")
    public Result searchUserInfo(User user){
        PageInfo<User> info=userService.searchUserInfo(user);
        return Result.success(info);
    }
}

注:可单独的书写跨域配置配置类(可参考:在 Spring 应用中处理 CORS 跨域 - spring 中文网)

2.5、UserService接口类 

public interface UserService {
    PageInfo<User> searchUserInfo(User user);
}

2.6、UserServiceImpl接口实现类

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;

    @Override
    public PageInfo<User> searchUserInfo(User admin) {
        // 开启分页查询
        PageHelper.startPage(admin.getCurrentPage(), admin.getPageSize());
        // 接下来的查询会按照当前开启的分页设置来进行查询
        List<User> list=userMapper.searchUserInfo(admin);
        return PageInfo.of(list);
    }
}

2.7、UserMapper类

@Repository
public interface UserMapper extends Mapper<User> {

    List<User> searchUserInfo(@Param("user") User user);
}

2.8、UserMapper.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.example.demo.dao.UserMapper">
    <select id="searchUserInfo" resultType="com.example.demo.entity.User">
        select * from admin
        <where>
            <if test="user != null and user.name != null and user.name != ''">
                and name like concat('%',#{user.name},'%')
            </if>
            <if test="user != null and user.phone != null and user.phone != ''">
                and phone like concat('%',#{user.phone},'%')
            </if>
        </where>
    </select>
</mapper>

2.9、User实体类

@Table(name = "admin")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column(name = "name")
    private String name;
    @Column(name = "password")
    private String password;
    @Column(name = "age")
    private Integer age;
    @Column(name = "sex")
    private String sex;
    @Column(name = "phone")
    private String phone;

    @Transient
    private Integer currentPage;
    @Transient
    private Integer pageSize;
}

注: @Column注解的字段与数据库字段一致可省略,@Transient注解的字段代表不是数据中的字段。

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值