一、项目概述

本文记录了基于若依(RuoYi)前后端分离框架开发学生信息管理模块的完整过程。若依框架是一个基于 Spring Boot + Vue 的权限管理系统,提供了完善的代码生成器,能够快速实现 CRUD 功能。

开发环境:

后端:RuoYi-Vue v3.8.2

前端:Vue 2 + Element UI

开发工具:IntelliJ IDEA

数据库:MySQL

版本控制:Git

二、数据库设计

2.1 创建学生信息表

首先在 MySQL 数据库中创建学生信息表 my_student

CREATE TABLE `my_student` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '编号',
  `name` varchar(30) DEFAULT NULL COMMENT '学生名称',
  `sex` char(1) DEFAULT NULL COMMENT '性别(0男 1女 2未知)',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生信息表';

2.2在ruoyi系统中导入数据库表my_student

  1. 登录若依管理系统,进入后台

  2. 找到"系统工具"菜单(左侧菜单栏)

    • 点击"系统工具"
    • 点击"代码生成"
  3. 导入表操作

    • 在代码生成页面,点击"导入"按钮
    • 会弹出"导入表"对话框
    • 在表名称输入框中输入:my_student(或者直接搜索)
    • 在表列表中找到并勾选 my_student 表(表描述应该显示"学生信息表")
    • 点击"确定"按钮
       
  4. 确认导入成功

    • 导入后,能在代码生成列表中看到 my_student 这条记录
    • 表名称:my_student
    • 表描述:学生信息表
    • 实体:MyStudent
    • 创建时间会显示当前时间

2.3填写相关信息

在代码生成列表中,找到 my_student 这一行,点击右侧的"编辑"按钮,进入编辑页面。填写三个标签页的信息:

1. 基本信息标签页(保持默认即可)

2. 字段信息标签页(保持默认即可)

3. 生成信息标签页(重点)

点击"生成信息"标签,填写以下内容:

生成模板:选择"单表(增删改查)"(可以自己研究下拉选项)

生成包路径com.ruoyi.system(默认)

生成模块名system(默认)

生成业务名student

生成功能名学生信息

上级菜单:选择"系统工具"(为了演示方便,暂且放在已有菜单下。也可以先自定义一个菜单,再选择它)

生成代码方式:选择"zip压缩包"

填写完成后,点击页面底部的"提交"按钮。

2.4下载生成文件

  1. 提交成功后,会回到代码生成列表页面

  2. 找到 my_student 这一行,在右侧"操作"列中,点击"生成代码"按钮

  3. 系统会自动下载一个 zip压缩包到你的电脑(通常在下载文件夹)

  4. 解压这个zip文件,会看到里面有三个文件夹:

    • main 文件夹(后端Java代码)
    • vue 文件夹(前端Vue代码)
    • studentMenu.sql 文件(菜单SQL脚本)

       

2.5拷贝到对应目录、导入sql文件更新menu表

2.5.1 拷贝后端代码

将解压后的 main 文件夹里的内容,拷贝到你的若依项目中:

路径:ruoyi-system/src/main/

注意:Controller 要单独放在 ruoyi-admin 模块的 Controller 包下

2.5.2 拷贝前端代码

将解压后的 vue 文件夹里的内容,拷贝到前端项目中:

api 文件夹 → 拷贝到 ruoyi-ui/src/api/

views 文件夹 → 拷贝到 ruoyi-ui/src/views/

2.5.3 导入SQL文件

  1. 打开 Navicat,连接到你的数据库
  2. 右键点击数据库名,选择**"运行SQL文件"**
  3. 选择解压出来的 studentMenu.sql 文件
  4. 点击"开始"按钮执行
  5. 看到"Finished successfully"表示成功

2.5(详细步骤)

第一步:找到下载的zip文件

  1. 打开下载文件夹(通常是 C:\Users\你的用户名\Downloads\
  2. 找到刚才下载的zip文件(文件名类似 ruoyi.zip )
  3. 右键点击zip文件 → 选择"解压到当前文件夹"或"解压到..."
  4. 解压后会看到三个东西:
    • main 文件夹
    • vue 文件夹
    • studentMenu.sql 文件

第二步:打开解压后的main文件夹

  1. 双击打开 main 文件夹
  2. 继续双击打开 java 文件夹
  3. 继续双击打开 com 文件夹
  4. 继续双击打开 ruoyi 文件夹
  5. 继续双击打开 system 文件夹
  6. 看到以下文件夹:
    • controller 文件夹
    • domain 文件夹
    • mapper 文件夹
    • service 文件夹

第三步:拷贝domain文件夹

  1. 选中 domain 文件夹
  2. 右键 → 复制
  3. 打开项目目录:D:\Data (D:)\RuoYi-Vue-v3.8.2\ruoyi-system\src\main\java\com\ruoyi\system\(这是我的项目目录,请打开你们自己的目录)
  4. 在这个目录下右键 → 粘贴
  5. 如果提示"已存在domain文件夹",选择"合并""全部替换"

第四步:拷贝mapper文件夹

和第三步步骤相同,也是粘贴到同一个地方

第五步:拷贝service文件夹

和第三步步骤相同,也是粘贴到同一个地方

第六步:拷贝MyStudentMapper.xml文件

  1. 回到解压的zip文件根目录
  2. 打开 main → resources → mapper → system 文件夹
  3. 会看到 MyStudentMapper.xml 文件
  4. 复制这个文件
  5. 粘贴到项目的:D:\Data (D:)\RuoYi-Vue-v3.8.2\ruoyi-system\src\main\resources\mapper\system\(这是我存放ruoyi的目录,这里选你自己的目录)

第七步:拷贝Controller文件(特殊处理)

  1. 回到解压的 main\java\com\ruoyi\system\controller\ 文件夹
  2. 找到 MyStudentController.java 文件
  3. 复制这个文件
  4. 粘贴到:D:\Data (D:)\RuoYi-Vue-v3.8.2\ruoyi-admin\src\main\java\com\ruoyi\web\controller\system\ (注意:是 ruoyi-admin 模块,不是 ruoyi-system)

第八步:拷贝前端vue文件

  1. 回到解压的zip文件根目录

  2. 打开 vue 文件夹,会看到:

    • api 文件夹
    • views 文件夹
  3. 复制 api 文件夹里的内容

  4. 粘贴到:D:\Data (D:)\RuoYi-Vue-v3.8.2\ruoyi-ui\src\api\(这是我存放ruoyi的目录,这里选你自己的目录)

  5. 复制 views 文件夹里的内容

  6. 粘贴到:D:\Data (D:)\RuoYi-Vue-v3.8.2\ruoyi-ui\src\views\(这是我存放ruoyi的目录,这里选你自己的目录)

第九步:在Navicat中导入SQL文件

  1. 打开Navicat,连接到你的MySQL数据库

  2. 在左侧找到你的若依数据库(应该叫 ry-vue 或类似名称)

  3. 右键点击这个数据库名称

  4. 在弹出菜单中选择"运行SQL文件..."

  5. 在弹出的对话框中:

    • 点击"..."按钮(文件路径右边的按钮)
    • 找到你解压的zip文件夹中的 studentMenu.sql 文件
    • 选中它,点击"打开"
    • 编码选择:65001 (UTF-8)
    • 勾选"遇到错误时继续"
    • 勾选"在每个运行中运行多个查询"

  6. 点击"开始"按钮执行

  7. 等待执行完成,右侧会显示执行结果

    • 看到绿色进度条到100%
    • 显示 "[SQL] Finished successfully" 表示成功
  8. 点击"关闭"SQL导入成功后,menu表就更新了,系统菜单中会新增"学生信息"菜单项。

2.6 重新运行程序

2.6.1重启后端程序

2.6.2重启前端程序

2.6.3 验证结果

  1. 刷新浏览器后,点击左侧菜单栏

  2. 展开"系统工具"菜单

  3. 能看到新增的"学生信息"菜单项

  4. 点击"学生信息",会打开学生信息管理页面

  5. 这个页面应该有:

    • 查询表单
    • 新增按钮
    • 学生信息列表
    • 编辑、删除等操作按钮

三、CRUD 四大操作

1. C - Create(创建/新增)

2. R - Read(查询/读取)

3. U - Update(更新/修改)

4. D - Delete(删除)

四、后端代码开发

4.1 项目结构说明

后端代码主要分布在以下模块:

ruoyi-admin/
└── src/main/java/com/ruoyi/web/controller/system/
    └── MyStudentController.java          # 控制器

ruoyi-system/
├── src/main/java/com/ruoyi/system/
│   ├── domain/
│   │   └── MyStudent.java                # 实体类
│   ├── mapper/
│   │   └── MyStudentMapper.java          # Mapper 接口
│   └── service/
│       ├── IMyStudentService.java        # Service 接口
│       └── impl/
│           └── MyStudentServiceImpl.java # Service 实现类
└── src/main/resources/mapper/system/
    └── MyStudentMapper.xml               # MyBatis XML 映射文件

4.2 实体类(Domain)

创建 MyStudent.java 实体类,对应数据库表字段:

关键点:

继承 BaseEntity 获得创建时间、更新时间等通用字段

使用 @Excel 注解支持 Excel 导入导出功能

使用 readConverterExp 进行字典值转换

4.3 Mapper 接口

创建 MyStudentMapper.java 接口:

package com.ruoyi.system.mapper;

import java.util.List;
import com.ruoyi.system.domain.MyStudent;

public interface MyStudentMapper {
    public MyStudent selectMyStudentByStudentId(Long studentId);
    public List<MyStudent> selectMyStudentList(MyStudent myStudent);
    public int insertMyStudent(MyStudent myStudent);
    public int updateMyStudent(MyStudent myStudent);
    public int deleteMyStudentByStudentId(Long studentId);
    public int deleteMyStudentByStudentIds(Long[] studentIds);
}

由于我的代码注释太多,为了方便读者查看,我把注释多的代码直接复制到本文章中。

4.4 MyBatis XML 映射文件

创建 MyStudentMapper.xml,实现动态 SQL:

关键点:

使用 <if> 标签实现动态查询

支持模糊查询(like)

4.5 Service 层

接口 IMyStudentService.java

package com.ruoyi.system.service;

import com.ruoyi.system.domain.MyStudent;
import java.util.List;

public interface IMyStudentService {
    public MyStudent selectMyStudentByStudentId(Long studentId);
    public List<MyStudent> selectMyStudentList(MyStudent myStudent);
    public int insertMyStudent(MyStudent myStudent);
    public int updateMyStudent(MyStudent myStudent);
    public int deleteMyStudentByStudentIds(Long[] studentIds);
}

实现类 MyStudentServiceImpl.java

4.6 Controller 控制器

关键点:

使用 @PreAuthorize 进行权限控制

使用 @Log 注解记录操作日志

RESTful 风格的 API 设计

五、前端代码开发

5.1 前端项目结构

前端代码结构如下:

ruoyi-ui/
└── src/
    ├── api/system/
    │   └── student.js          # API 接口封装
    └── views/system/student/
        └── index.vue           # 学生管理页面

5.2 API 接口封装

创建 student.js 封装所有 API 请求:

5.3 Vue 页面开发

创建 index.vue 页面,包含查询、新增、修改、删除、导出等功能:

<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="学生名称" prop="name">
        <el-input
          v-model="queryParams.name"
          placeholder="请输入学生名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:student:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:student:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:student:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:student:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="studentList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="编号" align="center" prop="id" />
      <el-table-column label="学生名称" align="center" prop="name" />
      <el-table-column label="性别" align="center" prop="sex" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:student:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:student:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改学生信息对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="学生名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入学生名称" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listStudent, getStudent, delStudent, addStudent, updateStudent } from "@/api/system/student";

export default {
  name: "Student",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 学生信息表格数据
      studentList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        name: null,
        sex: null
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
      }
    };
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询学生信息列表 */
    getList() {
      this.loading = true;
      listStudent(this.queryParams).then(response => {
        this.studentList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        name: null,
        sex: null
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length!==1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加学生信息";
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids
      getStudent(id).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改学生信息";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.id != null) {
            updateStudent(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addStudent(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal.confirm('是否确认删除学生信息编号为"' + ids + '"的数据项?').then(function() {
        return delStudent(ids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('system/student/export', {
        ...this.queryParams
      }, `student_${new Date().getTime()}.xlsx`)
    }
  }
};
</script>

关键功能:

  1. 搜索功能:支持按学号、姓名模糊查询
  2. 表格展示:分页显示学生列表
  3. 权限控制:使用 v-hasPermi 指令控制按钮显示
  4. CRUD 操作:新增、修改、删除学生信息

六、代码部署与测试

6.1 将代码添加到项目

我将生成的代码文件添加到项目中:

可以看到新增的文件包括:

MyStudentController.java - 后端控制器

MyStudent.java - 实体类

MyStudentMapper.java - Mapper 接口

MyStudentService.java 和实现类

MyStudentMapper.xml - SQL 映射文件

student.js - 前端 API

student/index.vue - 前端页面

studentMenu.sql - 菜单权限 SQL

6.2 提交代码到 Git

执行 Git 命令提交代码:

git add .
git commit -m "添加学生信息管理模块"
git push origin master

从这里我们可以看到:提交了 20 个文件;新增了 950 行代码;删除了 5 行代码

从这里我们可以看到代码已推送到 Gitee;提交 ID:80023d1

6.3 Gitee 仓库验证

登录 Gitee 查看提交记录:

可以看到提交信息:

提交 ID:80023d1

提交信息:"添加学生信息管理模块"

提交时间:2026-04-28

七、同学拉代码功能测试

1.启动后端服务

2.启动前端服务

3.登录系统测试

访问 http://localhost:81,使用管理员账号登录后,可以看到新增的"学生信息"菜单。

测试功能点:

  1. 查询学生列表
  2. 新增学生信息
  3. 修改学生信息
  4. 删除学生信息
  5. 批量删除
  6. 导出 Excel

同学从gitee 仓库拉取下来的代码运行成功,且测试功能点都完好,没有问题。

八、开发总结与心得

8.1 若依框架的优势

通过本次开发,我深刻体会到若依框架的以下优势:

  1. 代码生成器强大:只需配置数据库表,即可自动生成前后端代码,大大提高开发效率
  2. 权限管理完善:内置 RBAC 权限模型,支持细粒度的按钮级权限控制
  3. 前后端分离:前后端独立开发、独立部署,职责清晰
  4. 代码规范统一:生成的代码遵循统一的编码规范,易于维护

8.2 开发过程中的收获

  1. 理解了 MyBatis 动态 SQL:通过 <if> 标签实现灵活的查询条件
  2. 掌握了 RESTful API 设计:使用 GET、POST、PUT、DELETE 对应查询、新增、修改、删除操作
  3. 学会了 Vue 组件化开发:将页面拆分为搜索表单、数据表格、操作按钮等独立组件

8.3 遇到的问题与解决

问题 :权限按钮不显示,报403错误

原因:当前用户角色未分配权限

解决:在系统管理 → 角色管理中为角色分配学生管理权限

结语

通过本次学生信息管理模块的开发,我系统地学习了若依框架的使用方法,掌握了前后端分离项目的开发流程。从数据库设计、后端接口开发、前端页面实现到最终的功能测试,每一个环节都让我对 Web 开发有了更深入的理解。

若依框架的代码生成器极大地提高了开发效率,但我们也不能完全依赖工具,理解底层原理、掌握核心技术才是最重要的。希望这篇博客能够帮助到正在学习若依框架的同学们!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐