SpringBoot学习笔记(持续更新)

17 篇文章 1 订阅
8 篇文章 0 订阅

要学习SpringCloud啦!但是SpringBoot是基础,所以需要开个篇补一下,这里学习的是黑马程序员的6小时快速入门SpringBoot,在这里记录一下,以防忘记,将来也方便复习!

day01 SpringBoot初级

在这里插入图片描述

SpringBoot概述

在这里插入图片描述
突发奇想:学习编程,一定要自顶向下学习,刚刚入门了SC,对整个开发部署流程有了一个大概的认知,在听SB的课程发现理解起来很容易,而且学习的目标性很强
为什么会有SB呢?
这就要聊一聊Spring的缺点了

在这里插入图片描述
使用SB就不用配置tomcat了,因为将其内置了

SpringBoot快速入门

在这里插入图片描述
创建maven项目:

在这里插入图片描述
在这遇到个小问题,我的module点了没反应,解决方法就是将插件koitlin禁用
选用maven的模块
在这里插入图片描述

在这里插入图片描述

接下来在pom.xml文件中导入起步依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.9.RELEASE</version>
    <relativePath/>
</parent>

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

然后定义controller
在这里插入图片描述

package com.itheima;

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

@RestController
public class HelloController {

    @RequestMapping("Hello")
    public String hello(){
        return "Hello Spring Boot!";
    }
}

接下来如何启动呢,那接下来就是springboot特有的引导类,引导类一般都是Application结尾的,这个相当于springboot的入口。

有个细节就是要把业务代码和这个引导类分开写,如

在这里插入图片描述
HelloApplication.java中的代码:(将main方法写在此类中)

package com.itheima;

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

/**
 * 此类为引导类,也就是SB项目的入口,在入口中写入main方法
 */
@SpringBootApplication
public class HelloApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class,args);
    }
}

最后在这运行项目,然后输入url,页面成功显示
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

但是啊,这又要写pom.xml文件,又要写引导类耗费时间,那么有没有一种更快的构建方式呢?
当然

在这里插入图片描述
在这里插入图片描述
接下来我们只需要直接写业务代码就ok
可以说是更加便捷了

SpringBoot起步依赖原理分析

在这里插入图片描述
在pom.xml文件中我们可以追溯到spring-boot-starter-parent的祖先类spring-boot-dependencies,这个类中的properties标签整合了各种常用技术的稳定版本,如图:
在这里插入图片描述
再往下有一个标签是dependencyManagement,这是版本锁定的意思,如果我们在父工程中定义了版本信息,将来我们的工程如果继承了父工程,那我们就不需要写版本信息,如果没有继承,那就得加上父工程的版本信息。

在这里插入图片描述

springboot 配置

分为一下几个部分:

在这里插入图片描述
简单介绍一下profile的功能就是,或者说为什么会有profile,因为我们在开发的时候使用的是开发环境,部署的时候使用的是生产环境,而测试的时候使用的是测试环境,但是三种环境使用的配置是不一样的,所有就需要动态切换这些配置,因此也就有了profile。

配置文件分类

在这里插入图片描述
其中.yml.yaml都指同一种文件类型,由此我们便知道了,后缀名为properties、yml和yaml的文件都是配置文件
在这里插入图片描述
如果同一个项目,既有.properties和.yml,则idea会优先配置properties文件的内容,如果yaml和yml并存会优先执行yml。
在这里插入图片描述

YAML

在这里插入图片描述
使用properties,它的格式是没有缩进的,但是yml有
在这里插入图片描述

yaml的语法:

在这里插入图片描述

YAML数据格式

在这里插入图片描述
单引忽略,双引识别

server:
  port: 8082

name: abc

#对象
person:
  name: zhangsan
  age: 13
#对象行内写法
person1: {name: lisi,age: 14}

#地址
address:
  - beijing
  - shanghai

#地址行内写法
address1: [beijing,shanghai]

msg1: 'hello \n world'
msg2: "hello \n world"

在这里插入图片描述
在这里插入图片描述

读取配置文件信息

在这里插入图片描述

在这里插入图片描述

@Value

    @Value("${name}")			//使用@Value来读取值
    private String name1;		
    
    @Value("${person.name}")		//使用@Value来读取对象
	private String name2;	
	
     @Value("${address[0]}")           //使用@Value来读取数组
     private String address1;	
Environment:

定义一个Environment对象,这个对象属于
在这里插入图片描述
要对这个对象进行@Autowire注解,并且调用这个对象的getProperty()方法来获取配置内容,这个方法括号内要加双引号

    @Autowired
    private Environment env;
    
    @RequestMapping("/hello")
    public String hello(){
        System.out.println(env.getProperty("person.age"));
        return "SB 222!";

value注解适用于少数的配置内容获取,获取一两个配置可以用value,但是要获取大量的配置内容建议用Environment对象,只需要写一个@Autowire注解就可以使用方法多次调用,这样看起来美观一点。

configrationPeoperties

我们要在新建的Person类中获取配置文件中的Person对象的name和age
在这里插入图片描述
现在Person类中写入相对应的get set 方法

@Component                                     //此注解表示这个Person类被Spring所识别,它是一个bean
@ConfigurationProperties(prefix = "person")  //表示要在配置文件中找有没有一个person的对象name和age,在这里prefix的作用是先预先锁定
public class Person {
    private String name;    //这里的name一定要与配置文件中的相同,下同
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Persion{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

在congtroll中注入Person类,用@Autowire注解,相当于创建了一个person对象

    @Autowired
    private Person person;

在这里插入图片描述
输出结果:成功!
在这里插入图片描述
小结:使用environment和configrationProperties时,都需要在controller中采用@Autowire注解

接下来是获取配置中的数组并打印:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

profiles

在这里插入图片描述

在这里插入图片描述
dev:开发环境,pro:生产环境

profile配置方式
多profile方式:

在这里插入图片描述

yml多文件方式:

创建一个application.yml文件,在yml中

在这里插入图片描述

profile激活方式
配置文件

在application.properties中输入

spring.profiles.active=dev

表示激活application-dev.properties中的配置。

虚拟机参数

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
参数为-Dspring.profiles.active=test
这样配置,运行时就会提示说端口号为test的端口号

命令行参数

在这里插入图片描述
命令:--spring.profiles.active=pro
同时,我们可以将我们的项目打包,然后在命令行运行jar包,同时激活环境
在jar包目录下运行:
java -jar .\springboot-profiles-0.0.1-SNAPSHOT.jar便可启动服务
在这里插入图片描述
同时可以用--spring.profiles.active=dev指定环境

完整命令:java -jar .\springboot-profiles-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
在这里插入图片描述
使用虚拟机参数和命令行参数就可以不用动我们的代码,进行切换啦

在这里插入图片描述

内部配置加载顺序

在这里插入图片描述

有config就找conifg,
记一下在这遇到的问题,还没解决,就是在properties中配置了服务器端口号为8081,但是跑起来的端口号竟然是8084
厚礼谢,这个问题,我在看完视频之后解决了
因为我的代码是粘贴的黑马的,他在当前大项目springboot下的config中新建了properties文件,在其中配置了端口号为8084,而我是在小项目springboot-config里面的properties文件中配置的端口号8081,
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
结合内部配置加载顺序的那张图,我瞬间明白!!我心里暗喜,那接下来已运行端口号应该是8081了吧,结果竟然是8083 ???
我发现还有个properties在当前目录下,里面的port正是8083,结合内部配置加载顺序的那张图,我又一次大惊,并暗喜,搜嘎!
在这里插入图片描述
最后我将其他的properties文件都注释掉,只留了小项目的8081,一运行,ok,问题解决!
在这里插入图片描述
加载有顺序,所以小项目里的配置最终也会被执行,配置上下文路径,加一个hello
在这里插入图片描述
再写一个controller,接下来访问就需要hello/hello了
在这里插入图片描述
在这里插入图片描述

外部配置加载顺序

在这里插入图片描述
在这里插入图片描述
上图为官方网站17个外部配置的优先顺序,其中命令行排在第四,一般用命令行来配置
下面是命令行配置端口我上下文路径的命令:

java -jar .\springboot-config-0.0.1-SNAPSHOT.jar --server.port=8082		

java -jar .\springboot-config-0.0.1-SNAPSHOT.jar --server.port=8082 s--server.servlet.context-path=/hehe

在外部还有一种方式是通过命令行执行配置文件,需要输入配置文件的地址
在这里插入图片描述

java -jar .\springboot-config-0.0.1-SNAPSHOT.jar --spring.config.location=e://application.properties

小结:
所以SpringBoot提供这种多位置可以配置文件的方式,形成了多文件的一种互补方式
配置信息可以写在配置文件中(内部),也可以在运行时写入命令行中(外部)

SpringBoot整合其他框架

整合Junit

在这里插入图片描述

测试类,要测什么类,类名就是什么
准备测试UserService类

在这里插入图片描述
在这里插入图片描述
打印输出add

在这里插入图片描述

如果test的包名和java的包名一致,或者test的包是java包的子包,则可以不用指定@SpringBootTest中的classes,但是如果test和java的包名不一致且不是子包,则需要指定@SpringBootTest中的classes,如果不指定就会报错。
例如:
在这里插入图片描述
而如果是运行下图中两个方框的类,则不需要指定classes,因为1是与java包名一致的,而2是Java包的子包
在这里插入图片描述

整合Redis

在这里插入图片描述
redis需要的依赖是NoSQL

在这里插入图片描述

在这里插入图片描述
运行之前要配置application.yml文件,还要打开redis服务器

spring:
  redis:
    host: 127.0.0.1    # redis的主机ip
    port: 6379

整合MyBatis

在这里插入图片描述
在这里插入图片描述

在yml文件中配置DataSource
DataSourse:用户名,密码,连接地址等等
在这里插入图片描述

在这里插入图片描述

在测试中注入对应的mapper接口类 ,并写入测试


    @Autowired
    private UserMapper userMapper;

    @Test
    public void testFindAll() {
        List<User> list = userMapper.findAll();
        System.out.println(list);

在运行过程中发现个问题:The server time zone value '�й���׼ʱ��' is unrecognized,解决方案为在yml文件中设置时区

# datasource
spring:
  datasource:
    url: jdbc:mysql:///springboot?serverTimezone=UTC	#其中///省略了对应的ip和端口,因为连接的是本地的mysql,设置时区
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver

day02 SpringBoot高级

一天搞定SpringBoot+Vue

在这里介绍一位大佬,一天讲完SringBoot+Vue
开发环境热部署:
不用重启应用便可在浏览器感知到文件的修改,详细过程可百度。

SpringBoot Controller

在这里插入图片描述
@Controller通常和thymeleaf模板引擎使用(前后端就不分离了),所以做前后端分离的项目@Controller注解不是重点,应为我们前端的页面是由Vue写的,所以一般使用@RestController,它会以文本的形式传给前端,前端再对数据进行处理,后端不会设计到页面相关的内容。

在这里插入图片描述
控制器如何去接受前端的前端的请求呢?主要是靠路由器映射

在这里插入图片描述
@RquestMapping的意思就是请求映射,就是你的请求映射到那个url路径,这个路径下有要呈现什么页面是前端框架做的事,后端只需要管哪些方法要起作用,要返回什么数据就行。

在这里插入图片描述

在这里插入图片描述
两个*的含义是后面可以跟多层,跟什么都行;
一个*只能跟一层,但是它可以匹配任意字符

在这里插入图片描述
可以使用@GetMapping("/getData")来代替上面的@RquestMapping
同时可以用@PostMapping("/upload")来代替@RequestMapping(value = "/upload",method = RequestMethod.POST)

假如是前端要传过来一些参数我要如何接收呢?
若传来的参数是nickname,只需要将参数写在对应的方法中,例如通过
http://localhost:8080/hello?nickname=zhangsan来传参nickname,我只需要在方法中写入这个参数

@RequestMapping(value = "hello")
public String hello(String nickname){
    return "hello"+nickname;
}

如果传来的参数和我方法中写的参数名称不一致,则需要在方法的参数前添加@RequsetParm(“nickname”)

@RequestMapping(value = "hello")
public String hello(@RequestParam(value = "nickname") String name){
    return "hello"+name;
}

一旦加了这个注解,那要想访问到这个方法则url中必须得有这个参数,如果用http://localhost:8080/hello访问则会报错,如果还想访问则再加一个required属性@RequestParam(value = "nickname",required = false )
如果选择body则是把数据放在请求体当中(此软件为ApiPost),因为POST是把数据放在请求体当中。

GET 提交参数一般显示在 URL 上,POST 通过表单提交不会显示在 URL 上,POST 更具隐蔽性
若代码里写的的POST方式,结果用GET请求,则会报405的错误,:
	"status": 405,
	"error": "Method Not Allowed

在这里插入图片描述
如果想把参数放在url中,则选择query,还可以采用json的方式,不过要在代码中加入@RequestBody放在方法的参数之前
在这里插入图片描述

    @RequestMapping(value = "/postTest4",method = RequestMethod.POST)
    public String postTest4(@RequestBody User user){
        System.out.println(user);
        return "POST请求";
    }

如果前端传过来的参数很多呢?比如说要注册一个账号,要用户名、密码、邮箱等等,再用url中拼接的方式就太low 了,我们一般采用面向对象的思想,将这些参数封装在一个类当中,切记类中的名称一定要和前端的名称一致,然后在方法中将此类作为参数。
例如:


//User.ajva
package com.example.helloworld.entity;

public class User {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}



//ParamsController.java
@RestController
public class ParamsController {

    @RequestMapping(value = "/postTest3",method = RequestMethod.POST)
    public String postTest3(User user){
        System.out.println(user);
        return "POST请求";
    }
  }

在这里插入图片描述
classpath是指编译完成之后的target目录中的classes目录

SpringBoot文件上传+拦截器

在这里插入图片描述
在这里插入图片描述
浏览器报错500,意味着后端出了错

在这里插入图片描述
上面是个示例图片,下面是源代码

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String up(String nickname, MultipartFile photo, HttpServletRequest request) throws IOException {
        System.out.println(nickname);
        // 获取图片的原始名称
        System.out.println(photo.getOriginalFilename());
        // 取文件类型
        System.out.println(photo.getContentType());

        String path = request.getServletContext().getRealPath("/upload/");
        System.out.println(path);
        saveFile(photo,path);
        return "上传成功";
    }

//
    public void saveFile(MultipartFile photo,String path) throws IOException {
//       判断存储的目录是否存在,如果不存在则创建
        File dir = new File(path);
        if(!dir.exists()){
//          创建目录
            dir.mkdir();
        }

        File file = new File(path+photo.getOriginalFilename());
        photo.transferTo(file);
    }
}

因为上传的文件最后是传在web服务器上,web服务器运行在linux上的,咱们这个程序最终是要部署到linux上的,最终要放在云端,所以我们需要动态地获取web服务器所在的位置,用HttpServletRequest对象和方法getServletContext().getRealPath(“/upload/”),这个"/upload/"路径其实不存在的,但是我们到时候可以利用自己写的saveFile方法创建出来。

在这里插入图片描述
用户发来的请求会先经过我们的拦截器,里面有三个方法
在这里插入图片描述
如果用户没有登录,或者没有获取到session则重定向到登录页面

在这里插入图片描述
在这里插入图片描述

RESTful服务+Swagger

RESTful是一种风格
在这里插入图片描述

后面会学习如何把数据库中的数据查询出来以json的方式返回给前端,这样前端就可以做渲染了

在这里插入图片描述
在这里插入图片描述
创建用户,或者说注册应该用POST

在这里插入图片描述
如何在实际编程中将API设置为RESTful风格的呢?
请求方法上:

在这里插入图片描述
URL的设置:只有名词,没有动词,并且名词与数据库中的表格相对应
在这里插入图片描述

举例:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

swagger可以帮我们做接口调试,还可以帮我们生成API文档(可以动态生成),这个文档用于前后端沟通

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码:这个代码只需要放在项目中即可,不用重复去写,因为实际在开发的时候只需要配置一次。

package com.example.helloworld.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration // 告诉Spring容器,这个类是一个配置类
@EnableSwagger2 // 启用Swagger2功能
public class SwaggerConfig {
    /**
     * 配置Swagger2相关的bean
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com"))// com包下所有API都交给Swagger2管理
                .paths(PathSelectors.any()).build();
    }

    /**
     * 此处主要是API文档页面显示信息
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("演示项目API") // 标题
                .description("演示项目") // 描述
                .version("1.0") // 版本
                .build();
    }
}

到时候文档会在这个路径下http://localhost:8080/swagger-ui.html#/user-controller,里面可以读到我们写的所有的控制器
在这里插入图片描述

@ApiOperation("获取用户")中@ApiOperation的作用,就是在http://localhost:8080/swagger-ui.html#/user-controller中对应的controller上显示注释内容,以便更好理解
在这里插入图片描述
下面还有一些常见的注解:
在这里插入图片描述
那它如何做接口调试呢?
在这里插入图片描述
然后就可以输入参数,执行了:
在这里插入图片描述

MybatisPlus快速上手

在这里插入图片描述
ORM是一种技术理念,而MyBatis是ORM框架的一种实现,但是MyBatis还需要写一些配置,MybatisPlus在Mybatis的基础上做了增强,只需要做很少的配置就可以使用。

在这里插入图片描述
先讲Mybatis,再讲MybatisPlus
导入依赖:

        <!--  MyBatisPlus依赖  -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!-- mysql驱动依赖  -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--    数据连接池 druid    -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.20</version>
        </dependency>

我们在使用数据库的时候,最好使用连接池的技术,让他一次性申请多个连接,提高数据库的连接效率。
在这里插入图片描述

数据库的操作我们一般就在mapper这个包下面,在写包名的时候最好复制,如何复制呢?

在这里插入图片描述
然后
在这里插入图片描述

代码:

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=root
spring.datasource.password=root
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
server.port=8088

在这里插入代码片在这里插入图片描述
mapper里面的都是接口,不需要是一个类,因为对于mybatis来讲我们不需要做实现的,只需要把这个方法的声明写上就可以了,所有数据库的操作呢都可以让mybaits来完成。
接口的名称呢一般用要操作的表加上Mapper结尾,然后在类名上写Mapper注解,这样才能扫到这个Mapper,那么里面怎么写呢?需要写上对应的方法声明,要做什么事情就写上对应的方法,然后将对应的SQL语句注解在方法上面。
那么如果我们要写一个查询方法,查询的话如果是返回多个对象则应使用集合List<要返回的对象>,而要返回的对象我们一般定义在entity(实体类)包中,里面的每一个类的属性应该与数据库的字段一致,查询的方法的名称是可以任意的,一般与操作同含义就可以,然后在方法上面注上查询的SQL,这个SQL会自动去寻找配置文件中的数据库,然后进行操作,然后它会自动将结果返回到这个List中。

项目结构:
在这里插入图片描述
然后我们需要在controller中创建一个User对象,接着用它调用对应的查询方法,但是我们自己创建很明显不符合IOC思想,所以我们只需要声明一个User对象,然后在上面注@Autowired,Spring会自动帮我们创建一个User的bean。

上面我们说了查询返回多个对象,然后这些数据我们一般要转成json再传给前端,前后端分离的项目一般是使用json来完成,如何转换呢?把controller中方法的返回类型改为List,这样就会自动转为json格式。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
mybatis早期的名字叫做ibatis,上面CRUD的操作在MybatisPlus中就可以不用写了,直接用UserMapper类继承BaseMapper然后传入一个User类,MybatisPlus会在数据库中找表名为User 的表进行操作,MybatisPlus的细节可以看官网哦,假如类名和数据库名称不一致,可以使用@TableName来告诉它表名是什么。

当我们需要插入数据的时候,数据库中如果设定了自动增长,我们就不必再在前端填入数据了,因为自动增长会把我们设定的覆盖掉。一般插入数据的时候,如果主键是可以自增的就将它设为自增的,如果主键是身份证号码则不可以设为自增。
没有下面这一条命令,我们输出的user对象,它的值其实跟数据库中的值是不一样的。
若主键需要设置为自增的,则 用@TableId(type = IdType.AUTO)对主键进行注解标识,就可实现,Java程序中对象的属性和数据库中的数据保持一致,如果不用这条注解,并且没有设置主键的值,但在数据库中设置了主键可以自增,那传入数据后数据库的数据是可以自增的,但是在Java程序中打印这些数据,主键的值将是默认的0,因为这条注解会使MybatisPlus先去数据库获取数据再打印输出。

例如:未打注解,未设置id,则打印输出0
在这里插入图片描述
打了注解,没有设置id,则是自增后的值
在这里插入图片描述

MybatisPlus相比于Mybatis那些方面做了增强?

MybatisPlus多表查询及分页查询

查询用户的时候想知道他还有什么订单,这时候就会涉及到多个表的关联查询

Vue框架快速上手

在这里插入图片描述
以前我们使用jquery,这个绑定的过程包括数据变化的过程需要我们自己去完成,有了vue我们只需要关心业务逻辑和数据就可以了,并且vue完全屏蔽了dom,在vue中几乎用不到什么document.get这种方法。
在这里插入图片描述

Vue组件化开发

第三方组件element-ui

Axios网络请求

前端路由VueRouter

状态管理VueX

前端数据模拟MockJS

vue-element-admin后台集成方案

项目地址

JWT跨域认证

SpringBoot+vue-element-template

阿里云服务器使用

SpringBoot+Vue云端环境配置SpringBoot+Vue项目云端部署

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fruit_Caller

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

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

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

打赏作者

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

抵扣说明:

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

余额充值