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

创建空项目

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

设置 maven

image.png

设置 utf-8

image.png
image.png

mavenDemo

image.png
image.png
image.png

  • 添加上相关 maven 内容

image.png

  • 运行小试

image.png

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

maven 仓库官网

maven仓库官网https://mvnrepository.com/tags/spring
在这里搜索或下载 maven 依赖

Lombok

Lombok 提供了一些注解
需要引入 Lombok 的依赖并安装 Lombok 的插件
image.png

导入依赖

image.png

测试 01

package com.example;

public class Student {
    private int id;
    private String name;
    private int age;
    
}
package com.example;

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

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

Lombok 测试

package com.example;

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

}
package com.example;

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

image.png
打印出来的不是地址了,说明@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 仓库中搜索并复制依赖
image.png
image.png

创建类

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;

}
package com.example;

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

image.png

gson 使用

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

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));
    }
}

image.png

  • gson 对于列表的转换也是一样的

springboot 和 mybatisplus

新建一个模块

image.png
选好之后下一步,然后选中自己需要的依赖,我们用是SpringBoot的一个脚手架创建的,所以里面有一些自带的依赖可以去选择,我们只需要两个依赖,一个是mysql的驱动依赖,还有mybatisplus的依赖,我们可以看到里面有mysql的依赖以及mybatis的依赖,我们需要使用的是mybatisplus,而不是mybatis,所以我们只选择mysql的依赖,创建好之后再去maven的坐标库去引入mybatisplus的依赖
还要选择上 spring web,用在实现在浏览器上进行相关显示
image.png
image.png
image.pngimage.png

启动类代码

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 依赖

		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
			<version>3.5.5</version>
		</dependency>

.yml 文件及其配置

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

  • 配置.yml 文件
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

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

image.png

mybatis-plus 代码生成器

建包

创建这些包
image.png

安装插件

image.png

配置插件

image.png

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

使用插件

image.png
image.png

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

点击 save、再点击 code generatro
image.png
image.png
可以看到相关文件及其代码生成了

其他设置

添加上这个注解
image.png
image.png

编写代码并测试

image.png

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();
    }
}

image.png
image.png

运行成功:
image.png
之所以为空,是因为这里表格数据为空

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

node 以及 npm 的简单使用

电脑上在此之前已经安装了 node 并配置了环境变量image.pngimage.png
在这里,可以直接写 JavaScript 代码
image.png


npm config get registry
可以查看 npm 从哪里安装下载东西
image.png
这个国内镜像已经设置好了,这个是淘宝的新版镜像
设置新地址的方式:
npm config set registry=新地址

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

使用 npm 安装一个包:
image.png

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
image.png


创建项目
vue create 项目名
我在这个目录下创建:
image.png
image.png
创建完成:
image.png
image.pngimage.png


使用 vscode 打开 文件夹
image.png
image.png
image.pngimage.png
成功!!!~~~
image.png

vue 使用

此前已经安装了这些插件了:
image.pngimage.png
image.png


vscode 打开 vue 项目 demo 文件夹
image.png

开始写代码

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


此时:

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

<script>
  export default {

  }
</script>

<style>

</style>
  • App.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>

image.png
image.png


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


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

  • StudentEgg.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
<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
image.png



  • StudentEgg.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
<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>

image.png

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

image.png

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

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

<style>

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

<script>
export default {

}
</script>

<style>

</style>
  • App.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>

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

组件传参
  • TestFile1.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
<template>
  <div>
    TestFile2组件被引用了
    <br>
    {{ qwe }}<!-- 2组件显示1组件传递的内容 -->
  </div>
</template>

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

<style>

</style>
  • App.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>

image.png

element-plus

image.png
image.png

安装并引用

npm install element-plus安装 elementplus
image.png
vue 引入 element-plus
image.png

演示一个按钮的使用:

image.png
可以直接把代码复制使用


未使用 elementplus 的样子

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

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

<style>
</style>
  • App.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>

image.png

使用 elementplus 的样子

  • StudentEgg.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
<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>

image.png


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

bootstrap 引入

image.png
image.png
安装 npm i bootstrap@5.3.0-alpha1
image.png

在 main.js 中引入:

import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'

image.png
再次启动 vue 项目
image.png

js 箭头函数

基本语法形式如下:

(param1, param2, ..., paramN) => {
  // 函数体
}

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

param => {
  // 函数体
}

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

(param1, param2) => expr // expr 是要返回的表达式

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

() => { /* 函数体 */ }

示例1:基本使用

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

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

const double = n => n * 2;
console.log(double(4)); // 输出:8

示例3:立即返回表达式

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

示例4:无参数函数

const sayHello = () => console.log("Hello, world!");
sayHello(); // 输出:Hello, world!

示例5:箭头函数与this

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:基本使用
传统函数表达式方式:

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

示例2:单参数
传统函数表达式方式:

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

示例3:立即返回表达式
传统函数需要显式使用return

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

示例4:无参数函数
传统函数声明方式:

function sayHello() {
  console.log("Hello, world!");
}
sayHello(); // 输出:Hello, world!

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

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
image.png
image.png
axios 本身就是一个函数,可以直接使用
image.png
image.png

解决跨域问题

当后端使用 8080 作为端口,前端使用 8081 作为端口;端口不一样,就存在跨域问题
httplocalhost8080这三个有一个不一样就存在跨域问题
解决:
在 controller 类上加上注解 @CrossOrigin(origins={"*","null"})@CrossOrigin(origins = "*")
视频教程里说是第一个,通义千问说第一个不行,需要第二个

  • 21
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

01红C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值