springboot3+mybatis-plus+vue3创建入门小项目[学生管理系统]01[学习篇]

创建空项目

创建了一个名为 studyBox的空项目

设置 maven

设置 utf-8


mavenDemo



  • 添加上相关 maven 内容
  • 运行小试

用到的网站或工具或注意事项

maven 仓库官网

maven仓库官网 ---https://mvnrepository.com/tags/spring

在这里搜索或下载 maven 依赖

Lombok

Lombok 提供了一些注解

需要引入 Lombok 的依赖并安装 Lombok 的插件

导入依赖

测试 01

java 复制代码
package com.example;

public class Student {
    private int id;
    private String name;
    private int age;
    
}
java 复制代码
package com.example;

public class Demo {
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student);
    }
}

当你在Java程序中直接打印一个对象的引用(比如使用System.out.println(student);),Java默认调用该对象的toString()方法来获取字符串表示。如果你没有为类重写toString()方法,它将使用从Object类继承来的默认实现,这个默认实现通常返回的是类名加上 '@' 符号和该对象的内存地址的十六进制表示,因此你会看到类似这样的输出:com.example.Student@1f36e63

Lombok 测试

java 复制代码
package com.example;

import lombok.Data;
@Data
public class Student {
    private int id;
    private String name;
    private int age;

}
java 复制代码
package com.example;

public class Demo {
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student);
    }
}

打印出来的不是地址了,说明@Data 注解帮忙写上了 toString 方法

Lombok 常用注解及其作用

Lombok提供了一系列强大且常用的注解来简化Java编程,减少样板代码,以下是一些核心注解及其作用:

  1. **@Data **: 这是一个组合注解,包含了@Getter, @Setter, @ToString, @EqualsAndHashCode, 和 @RequiredArgsConstructor的功能。使用这个注解的类会自动生成getter和setter方法,toString()方法,equals()hashCode()方法,以及一个包含所有带有@NonNull注解的参数的构造方法。
  2. **@Getter ** 和 **@Setter **: 分别为类的属性生成getter和setter方法。可以单独应用于每个属性,也可以应用于整个类以生成所有属性的getter或setter。
  3. **@ToString **: 自动生成toString()方法,通常用于以字符串形式输出对象的内容,便于调试和日志记录。
  4. **@EqualsAndHashCode **: 自动生成equals()hashCode()方法,这对于需要在集合中比较对象或作为哈希表的键非常重要。
  5. **@NoArgsConstructor **, **@AllArgsConstructor **, @RequiredArgsConstructor:
  • @NoArgsConstructor 生成一个无参构造函数。
  • @AllArgsConstructor 生成一个包含所有字段的全参数构造函数。
  • @RequiredArgsConstructor 自动生成一个构造函数,包含所有带有@NonNull注解的字段,帮助确保这些字段在对象创建时被初始化。
  1. **@Builder **: 提供了一个建造者模式的API,使得对象的创建更加灵活和可读,特别适用于有很多参数的类。
  2. **@Slf4j **: 自动为类添加一个静态的Logger实例,通常是private static final Logger log = LoggerFactory.getLogger(YourClass.class);,简化日志记录操作。
  3. **@Value **: 类似于@Data,但旨在创建不可变类,生成的类所有字段都是final的,并且只提供getter方法,没有setter。通常还会生成一个基于所有字段的equals()和hashCode()方法。
  4. **@SneakyThrows **: 允许你抛出受检异常而无需显式声明throws子句,让代码更简洁。
  5. **@Synchronized **: 自动为方法或代码块添加同步锁,类似于Java的synchronized关键字,但使用更简洁。

这些注解通过在编译时动态地修改字节码来实现功能,从而避免了手动编写大量的重复性代码,提高了开发效率和代码的可读性。

gson

gson 是一个可以把 Java对象转成 json 对象的库

导入依赖

在 maven 仓库中搜索并复制依赖

创建类

java 复制代码
package com.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    private int age;

}
java 复制代码
package com.example;

public class Demo {
    public static void main(String[] args) {
        Student student = new Student(1,"xiaoming",18);
        System.out.println(student);
    }
}

gson 使用

gson 是一个可以把 Java对象转成 json 对象的库

java 复制代码
package com.example;

import com.google.gson.Gson;

public class Demo {
    public static void main(String[] args) {
        Gson gson = new Gson();
        /*
        创建gson对象可以直接将Java对象转化成json
         */
        Student student = new Student(1,"xiaoming",18);
        System.out.println(gson.toJson(student));
    }
}
  • gson 对于列表的转换也是一样的

springboot 和 mybatisplus

新建一个模块

选好之后下一步,然后选中自己需要的依赖,我们用是SpringBoot的一个脚手架创建的,所以里面有一些自带的依赖可以去选择,我们只需要两个依赖,一个是mysql的驱动依赖,还有mybatisplus的依赖,我们可以看到里面有mysql的依赖以及mybatis的依赖,我们需要使用的是mybatisplus,而不是mybatis,所以我们只选择mysql的依赖,创建好之后再去maven的坐标库去引入mybatisplus的依赖

还要选择上 spring web,用在实现在浏览器上进行相关显示


启动类代码

java 复制代码
package com.example.sbdemo;

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

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

引入 mybatis-plus 依赖

sql 复制代码
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
			<version>3.5.5</version>
		</dependency>

.yml 文件及其配置

将文件夹 application.properties改为 application.yml

  • 配置.yml 文件
xml 复制代码
spring:
  application:
    name: sbDemo
  datasource:
    url: jdbc:mysql://localhost:3306/egg?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
  configuration:
    # 开启驼峰命名自动映射
    map-underscore-to-camel-case: true
    # 开启日志打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-aliases-package: com.baomidou.pojo
  # 扫描mapper文件
  mapper-locations: classpath:mapper/*.xml

数据库 sql

sql 复制代码
CREATE DATABASE IF NOT EXISTS egg DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
USE egg;

CREATE TABLE `stu` (
    `id` INT AUTO_INCREMENT, -- 自增主键
    `name` VARCHAR(64) NOT NULL, -- 非空姓名字段,最大长度64字符
    `sex` ENUM('M', 'F') DEFAULT NULL, -- 性别字段,枚举类型,可选'M'为男,'F'为女,默认值为NULL允许不填
    `classroom` VARCHAR(10) DEFAULT NULL, -- 班级字段,最大长度10字符
    `grade` DECIMAL(5, 2) DEFAULT NULL, -- 成绩字段,十进制数,最多5位数,小数点后2位
    PRIMARY KEY (`id`) -- 设定t_id为主键
) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 使用InnoDB存储引擎,字符集设为utf8

mybatis-plus 代码生成器

建包

创建这些包

安装插件

配置插件

这里的 dbUrl 是:

jdbc:mysql://localhost:3306/数据库名字?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai

使用插件


_要注意,这里创建的数据库的代码中,表格名、字段等都没有前缀,所以 _ **_TablePrefix_**这里什么也不需要填

点击 save、再点击 code generatro

可以看到相关文件及其代码生成了

其他设置

添加上这个注解

编写代码并测试

java 复制代码
package com.example.sbdemo.controller;


import com.example.sbdemo.entity.Stu;
import com.example.sbdemo.service.IStuService;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author author
 * @since 2024-05-21
 */
@RestController
@RequestMapping("/stu")
public class StuController {
    @Autowired
    private IStuService stuService;

    @GetMapping("/list")
    public List<Stu> list(){
        return stuService.list();
    }
}


运行成功:

之所以为空,是因为这里表格数据为空

现在为表格添加数据后再测试:

node 以及 npm 的简单使用

电脑上在此之前已经安装了 node 并配置了环境变量

在这里,可以直接写 JavaScript 代码


npm config get registry

可以查看 npm 从哪里安装下载东西

这个国内镜像已经设置好了,这个是淘宝的新版镜像

设置新地址的方式:
npm config set registry=新地址

之后如果需要更换新镜像,再重新设置

使用 npm 安装一个包:

vue 简单使用

vue3 脚手架

安装好 node 以及配置好 npm 之后:

安装 vue3 脚手架

Vue的脚手架名称由vue-cli改成了@vue/cli,如果以及全局安装了旧版本的vue-cli(1.x或2.x),最好先卸载(就算以前没安装也运行一下这句,万一安装了呢):
npm uninstall vue-cli -g

安装脚手架@vue/cli
npm install -g @vue/cli

检查是否安装成功及其版本
vue --version


创建项目
vue create 项目名

我在这个目录下创建:

创建完成:


使用 vscode 打开 文件夹


成功!!!~~~

vue 使用

此前已经安装了这些插件了:


vscode 打开 vue 项目 demo 文件夹

开始写代码

App.vue 文件的内容删成这样


此时:

  • StudentEgg.vue(这里的组件文件名应该是多个单词组合而成,并且每个单词首字母大写,否则项目启动失败)
vue 复制代码
<template>
  <div>
    <h1>学生信息管理系统</h1>
  </div>
</template>

<script>
  export default {

  }
</script>

<style>

</style>
  • App.vue
vue 复制代码
<template>
  <div id="app">
    <StudentEgg></StudentEgg><!-- 把组件放到页面上展示 -->
  </div>
</template>

<script>
/* 在App.vue文件中将组件Student.vue引入 */
import StudentEgg from "./components/StudentEgg.vue";
export default {
  name: 'App',
  components: {
    /* 把组件放到对象里 */
    StudentEgg
  }
}
</script>

<style>

</style>



因为安装了这个插件,所以可以快速创建 vue 组件代码:


@click、v-show、v-model、v-for

  • StudentEgg.vue
vue 复制代码
<template>
  <div>
    <h1>{{ name }}</h1>
    <button @click="test">弹窗</button>
    <br>
    <input v-model="number"/>
    <!-- v-model:当修改输入框里的内容的时候,number里的内容也会跟这变,双向绑定 -->
    <div v-show="false">
      <!-- 当v-show值为true,就显示div里的内容,值为false就不显示 -->
      这是一句用于测试的话
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return{
      name:"小明",
      number:"输入框默认文字"
    }
  },
  methods:{
    test(){
      alert("弹窗出来啦~~~")
    }
  }
};
</script>

<style>
</style>
  • App.vue
vue 复制代码
<template>
  <div id="app">
    <StudentEgg></StudentEgg><!-- 把组件放到页面上展示 -->
  </div>
</template>

<script>
/* 在App.vue文件中将组件Student.vue引入 */
import StudentEgg from "./components/StudentEgg.vue";
export default {
  name: 'App',
  components: {
    /* 把组件放到对象里 */
    StudentEgg
  }
}
</script>

<style>

</style>

打开 localhost:8081



  • StudentEgg.vue
vue 复制代码
<template>
  <div>
    <div v-for="stu in students" :key="stu.id">{{ stu.id }}{{ stu.name }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      students: [
        {
          id: 1,
          name: "小明",
        },
        {
          id: 2,
          name: "小白",
        },
        {
          id: 3,
          name: "小豆",
        },
      ],
    };
  },
};
</script>

<style>
</style>
  • App.vue
vue 复制代码
<template>
  <div id="app">
    <StudentEgg></StudentEgg><!-- 把组件放到页面上展示 -->
  </div>
</template>

<script>
/* 在App.vue文件中将组件Student.vue引入 */
import StudentEgg from "./components/StudentEgg.vue";
export default {
  name: 'App',
  components: {
    /* 把组件放到对象里 */
    StudentEgg
  }
}
</script>

<style>

</style>

vue 组件嵌套使用以及父组件给组件传参

嵌套使用
  • TestFile1.vue
vue 复制代码
<template>
  <div>
    <TestFile2/>
    <!-- 将组件展示在页面 -->
  </div>
</template>

<script>
import TestFile2 from "./TestFile2.vue"
/* 如果要在一个组件中使用另一个组件,就要把这个组件引入 */
export default {
    components:{
        TestFile2
        /* 把引入的组件名放到组件标签里就可以使用了 */
    }
}
</script>

<style>

</style>
  • TestFile2.vue
vue 复制代码
<template>
  <div>
    TestFile2组件被引用了
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>
  • App.vue
vue 复制代码
<template>
  <div id="app">
    <TestFile1/><!-- 把组件放到页面上展示 -->
  </div>
</template>

<script>
/* 在App.vue文件中将组件TestFile1.vue引入 */
import TestFile1 from "./components/TestFile1.vue";
export default {
  name: 'App',
  components: {
    /* 把组件放到对象里 */
    TestFile1
  }
}
</script>

<style>

</style>

在浏览器安装插件,打开 F12,可以看到不同组件之间的嵌套关系

组件传参
  • TestFile1.vue
vue 复制代码
<template>
  <div>
    <TestFile2 :qwe="chuandi"/>
    <!-- :qwe="name"是2组件接受1组件传递的参数  chuandi是接受的1组件的变量名,qwe用于存储1组件的参数,qwe也相当于一个变量,qwe名字可以随便取 -->
    <!-- 将组件展示在页面 -->
  </div>
</template>

<script>
import TestFile2 from "./TestFile2.vue"
/* 如果要在一个组件中使用另一个组件,就要把这个组件引入 */
export default {
    data(){
        return{
            chuandi:"1组件传递给2组件的内容"
        }
    },
    components:{
        TestFile2
        /* 把引入的组件名放到组件标签里就可以使用了 */
    }
}
</script>

<style>

</style>
  • TestFile2.vue
vue 复制代码
<template>
  <div>
    TestFile2组件被引用了
    <br>
    {{ qwe }}<!-- 2组件显示1组件传递的内容 -->
  </div>
</template>

<script>
export default {
    props:["qwe"]/* 2组件接受1组件的参数 */
}
</script>

<style>

</style>
  • App.vue
vue 复制代码
<template>
  <div id="app">
    <TestFile1/><!-- 把组件放到页面上展示 -->
  </div>
</template>

<script>
/* 在App.vue文件中将组件TestFile1.vue引入 */
import TestFile1 from "./components/TestFile1.vue";
export default {
  name: 'App',
  components: {
    /* 把组件放到对象里 */
    TestFile1
  }
}
</script>

<style>

</style>

element-plus


安装并引用

npm install element-plus安装 elementplus

vue 引入 element-plus

演示一个按钮的使用:

可以直接把代码复制使用


未使用 elementplus 的样子

  • StudentEgg.vue
vue 复制代码
<template>
  <div>
    <button @click="test">弹窗</button>
  </div>
</template>

<script>
export default {
  methods:{
    test(){
      alert("弹窗出来啦~~~")
    }
  }
};
</script>

<style>
</style>
  • App.vue
vue 复制代码
<template>
  <div id="app">
    <StudentEgg></StudentEgg><!-- 把组件放到页面上展示 -->
  </div>
</template>

<script>
/* 在App.vue文件中将组件Student.vue引入 */
import StudentEgg from "./components/StudentEgg.vue";
export default {
  name: 'App',
  components: {
    /* 把组件放到对象里 */
    StudentEgg
  }
}
</script>

<style>

</style>

使用 elementplus 的样子

  • StudentEgg.vue
vue 复制代码
<template>
  <div>
    <h1>{{ name }}</h1>
    <el-button type="primary" @click="test">弹窗按钮</el-button>
  </div>
</template>

<script>
export default {
  methods:{
    test(){
      alert("弹窗出来啦~~~")
    }
  }
};
</script>

<style>
</style>
  • App.vue
vue 复制代码
<template>
  <div id="app">
    <StudentEgg></StudentEgg><!-- 把组件放到页面上展示 -->
  </div>
</template>

<script>
/* 在App.vue文件中将组件Student.vue引入 */
import StudentEgg from "./components/StudentEgg.vue";
export default {
  name: 'App',
  components: {
    /* 把组件放到对象里 */
    StudentEgg
  }
}
</script>

<style>

</style>

类似的,需要什么就复制什么的代码

bootstrap 引入


安装 npm i bootstrap@5.3.0-alpha1

在 main.js 中引入:

vue 复制代码
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'

再次启动 vue 项目

js 箭头函数

基本语法形式如下:

javascript 复制代码
(param1, param2, ..., paramN) => {
  // 函数体
}

或对于只有一个参数的情况,圆括号可以省略:

javascript 复制代码
param => {
  // 函数体
}

如果函数体只有一条语句,并且这条语句是要返回的值,那么可以省略花括号和return关键字:

javascript 复制代码
(param1, param2) => expr // expr 是要返回的表达式

对于没有参数的情况,需要保留一对空的圆括号:

javascript 复制代码
() => { /* 函数体 */ }

示例1:基本使用

javascript 复制代码
const add = (a, b) => a + b;
console.log(add(2, 3)); // 输出:5

示例2:单参数省略圆括号

javascript 复制代码
const double = n => n * 2;
console.log(double(4)); // 输出:8

示例3:立即返回表达式

javascript 复制代码
const greet = name => `Hello, ${name}!`;
console.log(greet("Alice")); // 输出:Hello, Alice!

示例4:无参数函数

javascript 复制代码
const sayHello = () => console.log("Hello, world!");
sayHello(); // 输出:Hello, world!

示例5:箭头函数与this

javascript 复制代码
const person = {
  name: "Bob",
  introduce: function() {
    setTimeout(() => {
      console.log(`My name is ${this.name}`); // 输出:My name is Bob
    }, 1000);
  }
};

person.introduce();

在这个例子中,即使在setTimeout的回调函数中,箭头函数依然能正确地访问到外层person对象的this,输出"Bob"。


对于以上五个示例,不使用箭头函数是这样的:

示例1:基本使用

传统函数表达式方式:

javascript 复制代码
const add = function(a, b) {
  return a + b;
};
console.log(add(2, 3)); // 输出:5

示例2:单参数

传统函数表达式方式:

javascript 复制代码
const double = function(n) {
  return n * 2;
};
console.log(double(4)); // 输出:8

示例3:立即返回表达式

传统函数需要显式使用return

javascript 复制代码
const greet = function(name) {
  return `Hello, ${name}!`;
};
console.log(greet("Alice")); // 输出:Hello, Alice!

示例4:无参数函数

传统函数声明方式:

javascript 复制代码
function sayHello() {
  console.log("Hello, world!");
}
sayHello(); // 输出:Hello, world!

示例5:箭头函数与this的对应处理

在传统的函数中,this的值通常在函数调用时决定,因此为了保持与箭头函数相同的行为(即让this指向外部的person对象),我们可能需要使用变量来保存this的引用,或者直接使用方法绑定技术(如.bind()):

javascript 复制代码
const person = {
  name: "Bob",
  introduce: function() {
    var self = this; // 保存外部的this
    setTimeout(function() {
      console.log(`My name is ${self.name}`); // 输出:My name is Bob
    }, 1000);
  }
};

// 或者使用.bind(this)
person.introduce = function() {
  setTimeout(function() {
    console.log(`My name is ${this.name}`); // 输出:My name is Bob
  }.bind(this), 1000);
};

person.introduce();

axios 的简单使用

安装 axios:
npm install axios -g

axios 本身就是一个函数,可以直接使用

解决跨域问题

当后端使用 8080 作为端口,前端使用 8081 作为端口;端口不一样,就存在跨域问题
httplocalhost8080这三个有一个不一样就存在跨域问题

解决:

在 controller 类上加上注解 @CrossOrigin(origins={"*","null"})@CrossOrigin(origins = "*")

视频教程里说是第一个,通义千问说第一个不行,需要第二个

相关推荐
风_流沙5 分钟前
java 对ElasticSearch数据库操作封装工具类(对你是否适用嘞)
java·数据库·elasticsearch
亽仒凣凣12 分钟前
Windows安装Redis图文教程
数据库·windows·redis
亦世凡华、21 分钟前
MySQL--》如何在MySQL中打造高效优化索引
数据库·经验分享·mysql·索引·性能分析
YashanDB23 分钟前
【YashanDB知识库】Mybatis-Plus调用YashanDB怎么设置分页
数据库·yashandb·崖山数据库
ProtonBase34 分钟前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
QQ同步助手41 分钟前
如何正确使用人工智能:开启智慧学习与创新之旅
人工智能·学习·百度
流浪的小新1 小时前
【AI】人工智能、LLM学习资源汇总
人工智能·学习
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
云和数据.ChenGuang6 小时前
Django 应用安装脚本 – 如何将应用添加到 INSTALLED_APPS 设置中 原创
数据库·django·sqlite
woshilys6 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver