【学生选课管理系统】项目笔记

项目难点

涉及到多个关联的数据库

脚手架

在这里我使用的是element-plus框架👉
具体文献参考-> element-plus官网

  • 运行项目(同时运行前端和后端)

    1. program/xsxk/vue/package.json
    2. program/xsxk/springboot/src/main/java/com/example/SpringbootApplication.java
  • 在该脚手架中,加入了自定义异常检查 exception

遇到文件夹名称全红解决方案

IDEA中,如果项目目录显示红色,主要是有版本控制所导致的,解决办法就是------解除版本控制。

  1. 🔺打开 → File->setting->目录映射->VCS->null

一定要注意拼写拼写拼写

批注:formVisible 和 fromVisible

SpringBoot启动失败Application run failed的解决办法

★这个问题得具体问题具体分析,得看下面那些报错什么意思,不能直接去网上找解决办法,查阅好多博主写的文章都没解决,大致出现问题的原因如下:

  1. 注解问题:

    Controller、service层的注解缺失会造成创建bean时出现错误。

    @Controller@Service

  2. 依赖包缺失,检查pom配置文件

    检查pom.xml文件下是否缺失依赖或者有多余的依赖,判断是否对bean的正常创建有影响。

  3. xml包中存在空文件:

    在 XML格式声明中的编码伪属性前面必须有空格

  4. 报错信息:Error parsing Mapper XML. The XML location is 'file [D:\gitee\self_development\program\xsxk\springboot\target\classes\mapper\StudentMapper.xml]'. Cause: org.apache.ibatis.builder.BuilderException: An invalid property 'score' was found in mapping #{collegeId, score = #{score}. Valid properties are javaType,jdbcType,mode,numericScale,resultMap,typeHandler,jdbcTypeName

  • An invalid property -- 不合法属性

🔺在解决以上问题之后发现仍然不能运行,所以我就采取最原始的办法,将之前运行成功后写的那些文件一一删除,然后重新写一份,排除错误的代码,然后成功解决🎇(泪目)
真的是实在没有办法了,重写了一份,也不知道哪里有改动,反正就是没出错了 :(

  • 综上所述:还得是要养成一边写代码一边运行的习惯才行,然后记得备注和检查错别字😭

tableDate 和 tableData 找不同

  • 在网页上面显示请求成功,说明已经连接上数据库,但是依旧显示不出教师信息,说明是前端有问题,于是我反过来检查代码,嘿?你猜这么着,拼写错误!😊

⭐嘻嘻,注意不要犯低级错误喔~

405报错

一般是因为请求函数报错,经常是因为请求接口对不上缘故,多检查一下

复制代码
error: "Method Not Allowed"
path: "/teacher/update"
status: 405
timestamp: "2024-11-05T02:58:22.373+00:00"
  • GET / PUT / POST / DELETE

404报错

  • 接口UI有问题

图片上传失败

添加教师图片,明明已经显示avatar已经修改完成,但是怎么也上传不到数据库,我刚开始以为可能出错有以下几点:

  1. 前端没写好,对接不上
  2. FileController文档
  3. 接口

⚪然而无论我怎么检查代码完全都没有问题时候,灵光一闪,我教师类的avatar是不是没有写好。

🔺嘻嘻,果不其然,没有写getAvatar函数

  • 明明很简答的问题又耽搁很久时间,所以说细心细心再细心,不过能想到教师类的我简直就是天才。日常辛苦我自己了:)

请求错误

  1. 数据库申请代码报错

Cannot read properties of undefined (reading 'sex')

遇到这种报错,基本上是遇到了 xxx.sex,比如form.sex,如果这个xxx(form)是undefined,那么就会出现这样的报错。

点击没反应排查方法

  1. F12查看网络请求,接口和参数有无问题
  2. 后台是否报错
  3. 打断点判断出问题具体环节

user.role,

  • 那么如果这个user是个undefined(未被定义)的时候,再去访问这个user里面的某个属性变量的时候,就会报这种错误。

针对管理员和学生无法看到课程信息bug

  1. 导致teachid可以被三个角色定义,其他角色也调用到teacher的if语句中

  2. 由于教师数据库没有其他角色信息

  3. 故查询不到课程

java 复制代码
// 分页查询
const load = () => {
  let teacherId= null
  if(data.user.role === 'TEACHER') {
    teacherId = data.user.id
  }
  request.get('/course/selectPage', {
    params: {
      pageNum: data.pageNum,
      pageSize: data.pageSize,
      name: data.name,
      teacherId: teacherId  //误写成 data.user.id 
    }
  }).then(res => {
    data.tableData = res.data?.list
    data.total = res.data?.total
  })
}

遗忘知识点

  • type="primary" 表示这个按钮是"主要"按钮,通常用来表示主要操作或强调重要功能。例如,在一个表单中,"提交"按钮通常会被设置为主要按钮,以引起用户的注意。

在 Element UI 中,常见的按钮类型还有:

  • default: 默认按钮
  • success: 成功按钮
  • warning: 警告按钮
  • danger: 危险按钮
  • info: 信息按钮

  • el-form-item:是Element UI库中用来包裹表单项的组件。在表单里,每个表单项都放在el-form-item里,不仅能让布局更整齐,还能给这些项添加标签和做验证

el-form就是整个表单,而el-form-item就是里面的每一个小格子啦。每个el-form-item都可以有个label属性来显示标签,比如"用户名"、"密码"这些。然后里面就可以放各种输入框啦,像el-inputel-select这些。


  • autocomplete="off" -- 用来关闭浏览器的自动填充功能的。

在JavaScript或TypeScript项目中,import 语句用于导入模块。你提到的两种导入方式主要区别在于路径的不同,这会影响代码如何解析和加载相应的模块。

  1. 绝对路径 vs 相对路径

    • import request from "@/utils/request"; 使用了绝对路径(也称为别名路径)。这种路径通常由构建工具(如Webpack)配置的别名来解析。例如,@/ 可能被配置为项目的根目录。
    • import request from "../../utils/request"; 使用的是相对路径,从当前文件的位置向上两级目录找到 utils/request 模块。
  2. 依赖解析

    • 绝对路径:如果使用绝对路径,你需要确保构建工具已经正确配置了这些路径别名,否则会导致模块找不到的问题。
    • 相对路径:相对路径依赖于文件的物理位置,因此在不同的文件结构中可能需要调整路径。
  3. 可维护性

    • 绝对路径:使用绝对路径可以使你的模块导入更加简洁和一致,特别是在大型项目中,可以减少路径深度带来的复杂性。
    • 相对路径:相对路径更直观地反映了文件之间的层级关系,但在项目结构调整时可能需要频繁修改。

示例

  • **import request from "@/utils/request";**和
  • **import request from ".../.../utils/request";**的区别

假设项目结构如下:

复制代码
project-root/
│
├── src/
│   ├── components/
│   │   └── MyComponent.vue
│   ├── utils/
│   │   └── request.js
│
└── webpack.config.js
Webpack配置(webpack.config.js)
javascript 复制代码
const path = require('path');

module.exports = {
  // ...其他配置...
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  }
};
使用绝对路径

MyComponent.vue 中:

javascript 复制代码
import request from '@/utils/request';
使用相对路径

MyComponent.vue 中:

javascript 复制代码
import request from '../../utils/request';

总结

选择哪种方式取决于项目需求和团队约定。如果项目使用构建工具并且已经配置了路径别名,那么使用绝对路径会更加方便和一致。如果不使用构建工具或者项目较小,相对路径可能会更直接一些。


  • ElMessage.success('操作成功')

这个涉及到的知识点有:

  1. Element UI框架ElMessage.success('操作成功') 是 Element UI 框架中的一个方法,用于显示一个成功的提示信息。在使用该方法前,需要先引入 Element UI 框架。
  2. 字符串模板语法 :如果你想要在 ElMessage.success 中加入变量,可以使用 ES6 的字符串模板语法,例如:const name = "John"; ElMessage.success(Hello, ${name}!);。这样,变量 name 的值就会被插入到字符串中,输出的结果类似于:Hello, John!。你也可以使用拼接字符串的方式,例如:const name = "John"; ElMessage.success("Hello, " + name + "!");
  3. 全局重写 :对于 Vue.js 3,你可以通过在 main.js 文件中全局重写 app.config.globalProperties 来修改 ElMessage.success 的行为。
  4. 组件VNode的生成:无论组件嵌套多深,只要在 Vue.component 中定义全局组件,这些构造函数都会被添加到组件的原型链上。生成的文本和 my-button 组件的 VNode 会一起作为最终 #app VNode 的组成部分。
  5. Scope(作用域)和组件间通信:通过 scope 标签和自定义事件传递数据,推荐使用全局事件总线进行组件间的复杂通信。
  6. 组件定义位置:全局组件的定义应放在 Vue 实例创建之前,因为 Vue 实例在初始化时需要先知道所有的组件信息才能正确挂载。
  7. 确认操作:在用户执行一些重要的操作时,为了防止误操作,可以使用弹窗组件来进行二次确认。

  • placeholder
    它就是input和textarea标签的一个属性,用来在文本框内啥都没输入的时候显示灰色的提示文字。这样用户就知道该填啥啦!不过啊,placeholder属性还没被CSS标准收进去哦。不同浏览器得用不同的伪元素来改它的样式
  1. 比如Chrome、Edge这些就用 ::webkit-input-placeholder
  2. Firefox用的是 ::-moz-placeholder

  • @RequestParam和@RequestBody
JavaScript 复制代码
public Result selectPage(@RequestParam(defaultValue = "1") Integer pageNum,
                         @RequestParam(defaultValue = "5") Integer pageSize) {

这段代码是一个Java方法的声明,通常用于Spring框架中的控制器类(Controller)。这个方法名为selectPage,它接受两个参数:pageNumpageSize,并返回一个Result对象。

知识点解释

  1. Spring MVC:

    • Spring MVC是Spring框架的一部分,用于构建Web应用程序。它使用控制器来处理HTTP请求,并将请求映射到相应的处理方法上。
  2. @RequestParam:

    • @RequestParam注解用于将HTTP请求参数绑定到控制器方法的参数上。
    • defaultValue属性指定了当请求中没有提供相应参数时使用的默认值。例如,如果请求中没有提供pageNum参数,那么它的默认值将是1;如果没有提供pageSize参数,那么它的默认值将是5。
  3. 分页查询:

    • 分页查询是一种常见的数据库操作,用于在大量数据中分批获取数据。pageNum表示当前页码,pageSize表示每页显示的数据条数。
  4. Result:

    • Result是一个自定义的返回类型,通常用于封装API的响应结果。它可以包含状态码、消息以及实际的数据内容。

@RequestParam 和 @RequestBody 的区别

  • @RequestParam:

    • 用于从URL请求参数中获取数据。

    • 适用于GET请求或POST请求中的表单数据。

    • 示例:

      java 复制代码
      @GetMapping("/example")
      public String example(@RequestParam String name) {
          return "Hello, " + name;
      }
  • @RequestBody:

    • 用于从HTTP请求体中获取数据,通常用于POST请求。

    • 适用于接收JSON、XML等格式的数据,并将其转换为Java对象。

    • 示例:

      java 复制代码
      @PostMapping("/example")
      public String example(@RequestBody User user) {
          return "User created: " + user.getName();
      }

总结

这段代码定义了一个分页查询的方法,通过@RequestParam注解从请求中获取分页参数,并返回一个封装了查询结果的Result对象。@RequestParam@RequestBody的主要区别在于它们获取数据的方式不同,前者从URL参数中获取数据,后者从请求体中获取数据。


  • < el-table-column label="职称" prop="title">< /el-table-column>中的prop是什么意思

在 Vue.js 框架中,el-table-column 是 Element UI 库中的一个组件,用于定义表格的列。prop 属性在这个上下文中表示该列对应的数据对象中的字段名。

具体来说,当你使用 el-table-column 时,你通常会将一个数组的数据传递给 el-table 组件,这个数组中的每个对象代表一行数据。prop 属性的值就是这些对象中的属性名,它告诉 el-table-column 应该从每行数据对象中提取哪个属性来显示在表格的这一列中。

例如:

html 复制代码
<el-table :data="tableData">
  <el-table-column label="姓名" prop="name"></el-table-column>
  <el-table-column label="年龄" prop="age"></el-table-column>
  <el-table-column label="职称" prop="title"></el-table-column>
</el-table>

假设 tableData 是这样的:

javascript 复制代码
[
  { name: '张三', age: 25, title: '工程师' },
  { name: '李四', age: 30, title: '经理' }
]

那么,el-table-columnlabel 属性会显示为 "职称",而 prop 属性会告诉表格从每个对象中提取 title 属性的值来填充这一列。因此,表格中第三列会显示 "工程师" 和 "经理"。


  • data.form = JSON.parse(JSON.stringify(row))
    这个代码片段是JavaScript中的一种深拷贝操作,涉及的知识点包括JSON对象、字符串和JavaScript对象的转换。具体来说,它使用了JSON.parse()JSON.stringify()两个方法来实现对象的深拷贝。

详细解释:

  1. JSON.stringify(row):

    • JSON.stringify() 是一个JavaScript内置的方法,用于将JavaScript对象转换为一个JSON格式的字符串。
    • 在这个例子中,它将变量row(假设它是一个对象)转换为一个JSON字符串。
  2. JSON.parse(...):

    • JSON.parse() 是另一个JavaScript内置的方法,用于将JSON格式的字符串解析成JavaScript对象。
    • 这里,它将之前通过JSON.stringify(row)得到的JSON字符串重新解析回一个新的JavaScript对象。

整体作用:

data.form = JSON.parse(JSON.stringify(row)) 这行代码的作用是将row对象进行深拷贝,并将结果赋值给data.form。深拷贝意味着新的对象与原对象之间没有引用关系,修改新对象不会影响到原对象。

涉及的知识点:

  • JSON (JavaScript Object Notation): 一种轻量级的数据交换格式。
  • JSON.stringify(): 将JavaScript对象转换为JSON字符串。
  • JSON.parse(): 将JSON字符串转换为JavaScript对象。
  • 深拷贝 vs 浅拷贝 :
    • 浅拷贝: 只复制对象的引用,不复制对象的内容。
    • 深拷贝: 完全复制对象及其子对象的内容,使得新旧对象之间互不影响。

示例代码:

javascript 复制代码
let row = {
    name: "Alice",
    age: 30,
    address: {
        city: "Wonderland",
        zipCode: "12345"
    }
};

let data = {};
data.form = JSON.parse(JSON.stringify(row));

console.log(data.form); // 输出:{ name: "Alice", age: 30, address: { city: "Wonderland", zipCode: "12345" } }

在这个例子中,data.formrow的一个深拷贝,对data.form的任何修改都不会影响到row

相关推荐
你要飞2 小时前
Hexo + Butterfly 博客添加 Live2D 看板娘指南
笔记
ajsbxi5 小时前
【Java 基础】核心知识点梳理
java·开发语言·笔记
呱呱巨基5 小时前
vim编辑器
linux·笔记·学习·编辑器·vim
新子y5 小时前
【小白笔记】普通二叉树(General Binary Tree)和二叉搜索树的最近公共祖先(LCA)
开发语言·笔记·python
聪明的笨猪猪5 小时前
Java JVM “调优” 面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
爱学习的uu6 小时前
CURSOR最新使用指南及使用思路
人工智能·笔记·python·软件工程
YuCaiH6 小时前
Linux文件处理
linux·笔记·嵌入式
Cathy Bryant6 小时前
大模型损失函数(二):KL散度(Kullback-Leibler divergence)
笔记·神经网络·机器学习·数学建模·transformer
qq_398586546 小时前
Threejs入门学习笔记
javascript·笔记·学习
hour_go7 小时前
TCP/IP协议相关知识点
网络·笔记·网络协议·tcp/ip