02. 带你开发一个基础的用户管理模块(上)

1132 字约 3 分钟读完12150 次阅读更新于 2026/5/3

创建一个 user 的数据库表

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '账号',
  `password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码',
  `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '姓名',
  `avatar` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '头像',
  `role` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '角色',
  `account` decimal(10,2) DEFAULT NULL COMMENT '账户',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='普通用户';

Vue 项目开发的基本方法

  1. 创建页面(views)
  2. 创建路由(router/index.js)
  3. 创建菜单(Manager.vue/ el-menu)

通过路由访问页面,例如:http://localhost:5173/manager/home

Element-Plus

https://element-plus.org/zh-CN/

Vue.js

https://cn.vuejs.org/

页面设计

基本的增删改查页面分为 4 部分:

  1. 搜索区域
  2. 操作区域(新增数据)
  3. 表格区域(展示数据、编辑删除数据)
  4. 分页区域

数据绑定

<el-input v-model="data.name" placeholder="Type something" :prefix-icon="Search" />

<script setup>
  import { reactive } from "vue";
  const data = reactive({
    name: null
  })
</script>

导入图标

import { Search } from "@element-plus/icons-vue";

表格分页展示数据(包括模糊查询)

数据库添加数据(造数据)

页面

请求数据

import request from "@/utils/request";

后台接口

user_name userName

  • entity(实体类,跟数据库表对应上,Java 里面的字段是驼峰的风格,数据库里面是下划线)
  • controller(接口层,跟前端交互,前端 vue 通过 axios 插件请求后端接口的数据)
  • service(业务逻辑层,写一下判断的业务逻辑,也会做多个表的数据更新,service 会调用 mapper 层操作数据)
  • mapper(数据接口层,全部都是接口方法,具体的实现在 xml 里面通过 sql 语句来实现)
  • mapper.xml(具体的 sql 的实现,namespace 绑定到 mapper 数据接口层)

分页查询使用 pageHelper 插件

/**
 * 分页查询的方法
 */
public PageInfo<User> selectPage(Integer pageNum, Integer pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    List<User> list = userMapper.selectAll();
    return PageInfo.of(list);
}

分页模糊查询的 SQL

完整的代码

User.java

UserController

package com.example.controller;

import com.example.common.Result;
import com.example.entity.User;
import com.example.service.UserService;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;


    /**
     * @param pageNum 当前页码
     * @param pageSize 每页展示的个数
     * @return 分页数据
     * 接口的请求方式:http://localhost:9090/user/selectPage?pageNum=1&pageSize=10
     */
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "1") Integer pageNum,
                             @RequestParam(defaultValue = "10") Integer pageSize,
                             @RequestParam(required = false) String name) {
        PageInfo<User> pageInfo = userService.selectPage(pageNum, pageSize, name);
        return Result.success(pageInfo);
    }

}

UserService

package com.example.service;

import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    @Resource
    private UserMapper userMapper;

    /**
     * 分页查询的方法
     */
    public PageInfo<User> selectPage(Integer pageNum, Integer pageSize, String name) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> list = userMapper.selectAll(name);
        return PageInfo.of(list);
    }

}


UserMapper

package com.example.mapper;

import com.example.entity.User;

import java.util.List;

public interface UserMapper {

    List<User> selectAll(String name);

}


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.mapper.UserMapper">

    <select id="selectAll" resultType="com.example.entity.User">
        select * from `user`
        <where>
            <if test="name != null">name like concat('%', #{name}, '%')</if>
        </where>
    </select>

</mapper>

User.vue

删除数据

页面按钮

<el-table-column label="操作" width="180" fixed="right" >
  <template #default="scope">
    <el-button type="danger" @click="del(scope.row.id)">删除</el-button>
  </template>
</el-table-column>

import {ElMessage, ElMessageBox} from "element-plus";

const del = (id) => {
  ElMessageBox.confirm('您确定删除吗?', '删除确认', { type: 'warning' }).then(res => {
    request.delete('/user/delete/' + id).then(res => {
      if (res.code === '200') {
        ElMessage.success('操作成功')
        load()
      } else {
        ElMessage.error(res.msg)
      }
    })
  }).catch(err => {})
}

后台接口

删除接口

/**
 * 删除数据
 * 接口路径:/user/delete/1
 */
@DeleteMapping("/delete/{id}")
public Result delete(@PathVariable Integer id) {
    userService.deleteById(id);
    return Result.success();
}

删除的 sql

<delete id="deleteById">
    delete from `user` where id = #{id}
</delete>