从简单项目入手Java(学生系统)V6(Web版本 Spring Boot3 MySQL Vue3 MyBatis)

经过前面五个版本的迭代,下面是一个企业级web版本的前后端分离学生系统

技术栈:SpringBoot3 + Vue3 + MySQL + MyBatis

整体架构说明

  • 后端:SpringBoot 提供接口(增删改查)
  • 数据库:MySQL(student 表)
  • 前端:Vue3 + Element Plus(浏览器网页)
  • 交互方式:HTTP 请求(前后端分离)

先在idea里面创建一个springboot项目(以下方法没成功,换了新建maven然后修改pom.xml的办法,但是也记录一下吧)

依赖勾选:

  • Spring Web
  • MySQL Driver
  • MyBatis Framework
  • Lombok

但是很不巧,下载构建spring boot的速度太慢了,始终没反应,还是按照创建maven项目的方法来吧

在maven项目的pom.xml里面粘贴以下配置,把它变成 Spring Boot 项目

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- Spring Boot 父项目 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.0</version>
        <relativePath/>
    </parent>

    <groupId>com.baosight</groupId>
    <artifactId>student-system</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- MySQL Driver -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- Spring Boot 打包插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

然后创建springboot入口类(启动类)

复制代码
package com.baosight.studentsystem;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StudentSystemApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudentSystemApplication.class, args);
    }
}

创建配置文件

在resources文件夹下new一个file,文件名是application.properties

复制代码
server.port=8080

# MySQL 连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/student_system?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# MyBatis 配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.baosight.studentsystem.entity

然后再刷新maven依赖,这样子再external Libraries里面就会有相关包

但是还是跑不起来,查看后发现是jdk版本25太高,需要21

安装好jdk21就能运行了

测试启动成功,改一下启动类,位置com.baosight.StudentSystemApplication

复制代码
package com.baosight;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.baosight.mapper")
public class StudentSystemApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudentSystemApplication.class, args);
    }
}

这里@开头的叫做注释,是给程序看的一种标签或者指令

@SpringBootApplication

作用:这是整个项目的 "总开关"

@MapperScan("com.baosight.mapper")

作用:告诉 SpringBoot 去哪里找数据库操作文件

这两加起来就是" 我是启动类,项目从我这跑,并且去 mapper 包找数据库操作**"**

以后还会遇到的高频注解(超级重要)

Controller 层(接口层)

复制代码
@RestController     // 这是接口控制器,返回JSON
@RequestMapping("/student")  // 设置访问路径 如:localhost:8080/student
@GetMapping          // 查询用
@PostMapping         // 新增用
@DeleteMapping       // 删除用
@PutMapping          // 修改用

作用:接收前端 Vue 的请求

Service 层(业务层)

复制代码
@Service     // 这是业务类,交给Spring管理

Mapper 层(数据库层)

复制代码
@Mapper       // 标记这是数据库操作接口(和@MapperScan二选一即可)

实体类 Entity(和表对应)

复制代码
@Data          // Lombok注解:自动生成get/set/toString
@TableName("student")  // 对应数据库表名

常用功能注解

复制代码
@Autowired     // 自动注入对象(不用new)
@Component     // 通用组件
@Configuration // 配置类

超简记忆口诀

  • @SpringBootApplication → 启动
  • @MapperScan → 找数据库
  • @RestController → 写接口
  • @Service → 写业务
  • @Autowired → 自动拿对象
  • @Data → 自动生成 get set

新建一下entity包,作为实体类,创建一个Student类,位置com.baosight.entity.Student

复制代码
package com.baosight.entity;

import lombok.Data;

@Data
public class Student {
    private String id;
    private String name;
    private Integer age;
}

com.baosight 包下新建 entity 子包

  1. 右键 com.baosight 包 → NewPackage
  2. 输入包名:com.baosight.entity
  3. 回车,就能看到 entity 子包了。

entity 包下新建 Student

  1. 右键 com.baosight.entityNewJava Class
  2. 输入类名:Student
  3. 回车,文件自动生成 com.baosight.entity.Student

我们先把所有的包结构都创建好

每层对应什么角色

1. controller 控制器

对应 MVC 里的 C(Controller)

  • 接收前端发的请求(浏览器 / Vue / 小程序)
  • 接收参数、返回结果(JSON)
  • 不写业务逻辑,只负责接请求、调 service

2. service 业务层 + impl 实现类

  • 核心业务逻辑
  • 比如:登录判断、新增学生、分页查询、权限判断
  • 规范:
    • service 放接口(抽象方法)
    • service/impl 放接口的实现类,加 @Service

3. mapper 数据访问层

对应 SSM 里的 Dao 层

  • 专门和数据库 MySQL 打交道
  • 写 SQL、查数据、增删改查
  • MyBatis 里:mapper 接口 + xml 映射文件

4. entity 实体类

对应 MVC 里的 M(Model)

  • 和数据库表一一对应
  • 学生表 → Student 类,字段一模一样
  • 用来封装数据,在各层之间传递

5. 启动类

SpringBoot 入口,一键启动整个项目,自动加载所有配置、扫描注解。

复制代码
com.baosight
   ├── StudentSystemApplication.java  启动类
   ├── entity        实体
   ├── mapper        数据库
   ├── service       业务
   │    ├── impl     实现类
   ├── controller    接口

这个结构之后一直会用到

  • 几乎所有标准 SpringBoot / SSM 后台项目,都是这套目录结构
  • 本质就是:SSM 分层架构 + MVC 设计模式 结合出来的固定规范

1. 先讲 MVC 模式

MVC 三层:

  • M Modelentity 实体模型
  • V View → 前端页面 / Vue 页面(后台项目一般不写 View,只给接口)
  • C Controllercontroller 控制器

后台接口项目没有 View 视图 ,只保留:M + C,中间加业务层、数据库层。

2. 再讲 SSM 分层架构(Spring + SpringMVC + MyBatis)

SSM 标准四层架构:

  1. Controller 控制层 → 这里的 controller
  2. Service 业务层 → 这里的 service + impl
  3. Dao/Mapper 数据层 → 这里的 mapper
  4. Entity 实体层 → 这里的 entity

前端 Vue 发请求 →Controller 接收请求 →调用 Service 接口ServiceImpl 实现类 写业务逻辑 →调用 MapperMapper 操作 MySQL 数据库 →数据原路返回给 Controller →返回 JSON 给前端

每层只干自己的事,互不越界

  • Controller 不写 SQL、不写业务
  • Service 不直接操作数据库,只调 Mapper
  • Mapper 只写 SQL,不处理业务判断

题外话:mvc和ssm的关系

MVC 只有 3 层:M+V+C

SSM 在 MVC 基础上,扩充成了 5 层:Entity (M) → Mapper(dao) → Service → Controller (C) → View (V)

所以:**SSM 完全包含 MVC,还比 MVC 多了业务层、数据库层。**SpringBoot 项目结构 = SSM 分层 = 升级版 MVC

复制代码
启动类
entity     ← 对应 MVC 的 M
mapper     ← SSM 额外加的数据库层
service    ← SSM 额外加的业务层
controller ← 对应 MVC 的 C
前端Vue    ← 对应 MVC 的 V

创建Mapper 接口(数据库操作)位置com.baosight.mapper.StudentMapper

复制代码
package com.baosight.mapper;

import com.baosight.entity.Student;
import org.apache.ibatis.annotations.*;
import java.util.List;

@Mapper
public interface StudentMapper {

    @Select("select * from student")
    List<Student> findAll();

    @Insert("insert into student(id,name,age) values(#{id},#{name},#{age})")
    int add(Student student);

    @Delete("delete from student where id=#{id}")
    int delete(String id);

    @Update("update student set name=#{name},age=#{age} where id=#{id}")
    int update(Student student);
}

Mapper 层(数据库)注解

  • @Mapper → 我是数据库操作类
  • @Select → 查询
  • @Insert → 新增
  • @Delete → 删除
  • @Update → 修改

创建Service 接口(业务层)位置com.baosight.service.StudentService

复制代码
package com.baosight.service;

import com.baosight.entity.Student;
import java.util.List;

public interface StudentService {
    List<Student> list();
    boolean add(Student student);
    boolean delete(String id);
    boolean update(Student student);
}

创建Service 实现类,位置com.baosight.service.impl.StudentServiceImpl

Service 层(业务)注解

  • @Service → 我是业务处理类

  • @Resource → 自动把 Mapper 拿过来用

  • @Override重写 / 覆盖父接口 / 父类的方法 ,就是重新实现一遍接口里定义的空方法

    package com.baosight.service.impl;

    import com.baosight.entity.Student;
    import com.baosight.mapper.StudentMapper;
    import com.baosight.service.StudentService;
    import org.springframework.stereotype.Service;
    import javax.annotation.Resource;
    import java.util.List;

    @Service
    public class StudentServiceImpl implements StudentService {

    复制代码
      @Resource
      private StudentMapper studentMapper;
    
      @Override
      public List<Student> list() {
          return studentMapper.findAll();
      }
    
      @Override
      public boolean add(Student student) {
          return studentMapper.add(student) > 0;
      }
    
      @Override
      public boolean delete(String id) {
          return studentMapper.delete(id) > 0;
      }
    
      @Override
      public boolean update(Student student) {
          return studentMapper.update(student) > 0;
      }

    }

创建Controller(接口层,给前端调用)位置com.baosight.controller.StudentController

复制代码
package com.baosight.controller;

import com.baosight.entity.Student;
import com.baosight.service.StudentService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin
@RequestMapping("/student")
public class StudentController {

    @Resource
    private StudentService studentService;

    @GetMapping("/list")
    public Map<String, Object> list() {
        Map<String, Object> res = new HashMap<>();
        res.put("code", 200);
        res.put("data", studentService.list());
        return res;
    }

    @PostMapping("/add")
    public Map<String, Object> add(@RequestBody Student student) {
        Map<String, Object> res = new HashMap<>();
        boolean flag = studentService.add(student);
        res.put("code", flag ? 200 : 500);
        res.put("msg", flag ? "添加成功" : "添加失败");
        return res;
    }

    @PostMapping("/update")
    public Map<String, Object> update(@RequestBody Student student) {
        Map<String, Object> res = new HashMap<>();
        boolean flag = studentService.update(student);
        res.put("code", flag ? 200 : 500);
        res.put("msg", flag ? "修改成功" : "修改失败");
        return res;
    }

    @GetMapping("/delete")
    public Map<String, Object> delete(String id) {
        Map<String, Object> res = new HashMap<>();
        boolean flag = studentService.delete(id);
        res.put("code", flag ? 200 : 500);
        res.put("msg", flag ? "删除成功" : "删除失败");
        return res;
    }
}

这个类 = 前端 Vue 的 "入口" 前端要查学生、加学生、删学生,全都先来找这个类 !它就是 Controller 层(接口层)

@CrossOrigin作用是跨域允许前端 Vue(localhost:5173)调用后端(localhost:8080

  • @RestController → 我是接口,返回 JSON
  • @CrossOrigin → 允许前端调用
  • @RequestMapping("/student") → 统一前缀
  • @Resource → 注入 service

查询所有学生接口详解

  • @GetMapping("/list")GET 请求 ,地址:/student/list→ 前端用这个地址查所有学生

  • Map<String,Object> res = new HashMap<>();→ 创建一个返回给前端的统一格式(code + data)

  • res.put("code",200)→ 给前端状态码:200 = 成功

  • res.put("data", studentService.list())→ 调用 service 查数据,把学生列表放进 data 返回

  • return res→ 返回 JSON 给前端

返回给前端的样子

复制代码
{
  "code":200,
  "data":[{学生1},{学生2}]
}

这个类的作用总结

它就是后端给前端开的 4 个接口:

  1. /student/list → 查询
  2. /student/add → 新增
  3. /student/update → 修改
  4. /student/delete → 删除

前端只需要调用这 4 个地址,就能完成学生管理系统所有功能!

然后创建springboot配置文件 application.yml,在 resources 下新建 application.yml

之前测试的 application.properties 可以删掉

项目里现在还有一个 application.properties 文件,它和 application.yml 功能是一样的,保留一个就行。右键点它,选择 Delete 删掉就可以了,避免配置冲突。

复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/student_system?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

server:
  port: 8080

mybatis:
  configuration:
    map-underscore-to-camel-case: true

数据库表我已经创建好了,之前就有的student表

现在后端就是做好了。运行 StudentSystemApplication

针对与前端:

在针对vue开发时需要用到node.js,我们先来安装一下https://nodejs.org/

选择Windows的安装,一直点next就行

Node.js 是一个能让 JavaScript 在电脑本地运行的环境

以前的 JavaScript 只能在浏览器里跑,用来写网页交互。Node.js 让 JavaScript 可以像 Python/Java 一样,直接在电脑上执行命令、管理文件、创建项目。

Vue3 前端项目,就是用 JavaScript 写的。要创建 Vue 项目、安装依赖、启动前端服务,都必须靠 Node.js 里的 npm 命令才能完成。

安装好后点开cmd查看一下node -v和npm -v可以看到版本号就行了

这里有四个命令来建立一个vue项目

复制代码
# 1. 创建 Vue3 项目(名字叫 student-web)
npm create vite@latest student-web -- --template vue

# 2. 进入项目文件夹
cd student-web

# 3. 安装项目基础依赖
npm install

# 4. 安装 axios 和 element-plus
npm install axios element-plus

element-plus = Vue3 的现成 UI 组件库;axios = 专门负责 "发请求拿数据" 的工具

电脑上会生成一个 student-web 文件夹,这就是前端项目

平时在启动项目的时候也要起这个vue才行,不然前台就没起来

用vscode打开看到结构是这样

复制代码
student-web/
├─ src/
│  ├─ main.js      ← 要修改的文件
│  ├─ App.vue      ← 要修改的文件
│  └─ style.css
└─ package.json

打开 src/main.js(main.js = Vue 项目的总入口、启动类,把原来的代码全部删掉,替换成下面这段:

复制代码
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue' // 新增
import axios from 'axios'

const app = createApp(App)

// 全局注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

app.config.globalProperties.$axios = axios
app.use(ElementPlus)
app.mount('#app')

main.js 一共干 5 件事:

  1. 创建 Vue 应用
  2. 导入全局样式
  3. 安装 ElementPlus(组件 + 图标)
  4. 挂载 axios(全局发请求)
  5. 挂载到页面,启动项目

打开 src/App.vue,把原来的代码全部删掉,替换成下面这段:

复制代码
<template>
  <div class="container" style="padding: 20px;">
    <h2>StudentmanagementSystem V6.0</h2>

    <el-form :model="stu" inline @submit.prevent="addOrUpdate">
      <el-form-item label="ID">
        <el-input v-model="stu.id" />
      </el-form-item>
      <el-form-item label="Name">
        <el-input v-model="stu.name" />
      </el-form-item>
      <el-form-item label="Age">
        <el-input v-model.number="stu.age" />
      </el-form-item>
      <el-button type="primary" native-type="submit">
        {{ isEdit ? 'refresh' : 'add' }}
      </el-button>
      <el-button @click="reset">Reset</el-button>
    </el-form>

    <el-table :data="list" border style="width: 600px;margin-top:20px">
      <el-table-column prop="id" label="ID" />
      <el-table-column prop="name" label="Name" />
      <el-table-column prop="age" label="Age" />
      <el-table-column label="operate">
        <template #default="scope">
          <el-button @click="toEdit(scope.row)">edit</el-button>
          <el-button type="danger" @click="del(scope.row.id)">delete</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'

const list = ref([])
const stu = ref({ id: '', name: '', age: '' })
const isEdit = ref(false)

const loadList = async () => {
  const res = await axios.get('http://localhost:8080/student/list')
  list.value = res.data.data
}

const addOrUpdate = async () => {
  if (isEdit.value) {
    await axios.post('http://localhost:8080/student/update', stu.value)
  } else {
    await axios.post('http://localhost:8080/student/add', stu.value)
  }
  loadList()
  reset()
}

const toEdit = (row) => {
  stu.value = { ...row }
  isEdit.value = true
}

const del = async (id) => {
  await axios.get('http://localhost:8080/student/delete?id=' + id)
  loadList()
}

const reset = () => {
  stu.value = { id: '', name: '', age: '' }
  isEdit.value = false
}

onMounted(() => {
  loadList()
})
</script>

准备就绪后,跑起来Springapplication

然后再cmd里面输入npm run dev

点击前端网址http://localhost:5173

可见项目运行成功

相关推荐
阿丰资源1 小时前
基于Springboot+mysql的在线兼职平台(附源码)
spring boot·后端·mysql
吴声子夜歌1 小时前
Java——Integer与二进制算法
java·算法
风味蘑菇干1 小时前
继承 + static + final 综合应用
java·开发语言
li星野2 小时前
二分查找六题通关:从标准模板到旋转数组(Python + C++)
java·c++·python
无所事事O_o2 小时前
IntelliJ IDEA 无法识别 Maven SNAPSHOT 依赖,但 Maven 编译正常
java
噢,我明白了2 小时前
MySql数据库数据基础操作(增删改查)
数据库·mysql·增删改查
yaoxin5211232 小时前
403. Java 文件操作基础 - 写入二进制文件
java·开发语言·python
未若君雅裁2 小时前
Redis Key 过期后会立刻删除吗?过期删除与内存淘汰策略详解
java·redis