SpringBoot2入门笔记
目标项目:项目介绍_哔哩哔哩_bilibili
技术栈:springboot + mybatis-plus + mysql + redis
基础篇
1.快速上手SpringBoot
1.1 idea联网创建boot项目‘

必须联网

–next,选择springboot项目用来干嘛的,我们是做mvc,也就是web

–创建成功

1.1.1 模拟创建一个控制器

1.1.2 直接run


1.2 idea不能正常联网?
–有时可能网站连接超时

1.3 官网创建boot项目

1.3.1 找到入口

–点击进入后向下翻
–Spring Initializr(初始化)
网址:Spring Boot

–就长这个样子

1.3.2 创建项目

1.3.3 导入依赖



1.3.3 点击生成压缩文件到本地


1.3.4 导入到idea工程
1.3.4.1 解压并移动到工程文件夹下

1.3.4.2 idea导入



1.3.5 创建一个控制类

1.3.6 直接run


1.4 boot官网不能访问?
–这是一个国外的网站,万一不能访问,那么1.1 和1.3的办法都将失效。
1.5阿里云实验室创建boot工程
官网:阿里云知行动手实验室-在浏览器沉浸式学习最新云原生技术 (aliyun.com)

1.5.1 创建工程


1.5.2 pom.xml修改boot版本

1.5.3 pom.xml文件爆红问题(未解决)
–关于打包的,暂时不打包,所以不影响运行

1.5.4 写一个控制器类

1.5.5 直接run


1.6 计算机不能联网?
–加入计算机不能联网,依旧能做boot
1.7 手工创建boot

1.7.1创建maven工程
–不需要骨架

1.7.2 修改pom.xml
–粘贴其他boot工程的pom.xml的部分配置

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.7.3 手写启动类(引导类)

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
1.7.4 写一个控制器类

1.7.5 直接run


2.入门核心
2.1 spring与boot对比
–boot全方位碾压


2.2 SpringBoot -parent

–导入依赖不用写版本号
–boot的parent已经辅助管理


2.3 SpringBoot -starter
–定义了若干个坐标的pom管理文件



2.4 Springboot -引导类
–注解内置初始化了spring容器
–默认扫描当前包与子包
–所以引导类(启动类)要放置在目录下


2.5 SpringBoot -内置tomcat


–这个就是内置tomcat核心

–如果想更换tomcat版本,修改版本号即可
–如果想切换其他服务器,例如jetty,undertow
–可以排除这个依赖,切换


3.小技巧
3.1 idea隐藏文件/目录
–boot项目结构有很多不需要处理的文件
–或者接收被人的项目目录中有许多不需要处理的文件
–我们不想看可以选择在idea中将他们隐藏

–具体操作

–最后,还是不建议去隐藏文件/目录
–程序员要直面所有文件
3.2 get一个小技巧 -比对文件


3.3 复制模块

–原则

①打开工程本地目录,复制一份

②并修改pom.xml的工程名
–这一步影响到idea读取boot配置,会很麻烦
–1.修改工程名
–2.删掉name标签 与 description标签

③删除其他配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RonbNrlH-1692968930954)(E:\文档\后端\SpringBoot\SpringBoot入门笔记\asset\image-20221107083334749.png)]
④idea工程中导入此模块,删掉name标签


4.SpringBoot基础配置
–maven工程的配置文件,卸载resources目录下的application.properties中
–是的,你没有听错
–boot的所有配置文件全部写在这里

4.1 属性配置

4.1.1 官网文档
官网:Spring Boot



–由于配置很多,可查官方文档
4.1.2 端口配置

#服务器的端口配置
server.port=9241
–观察启动日志


4.1.3 修改logo(广告位)

–比如配置off,logo消失

–也可以将logo换成图片

4.1.4 修改日志
–比如修改成error

4.2 配置文件分类
4.2.1 三种格式


–按照key + value的格式配置
–配置多了,就会眼花缭乱


4.2.2 三种格式的加载优先级

–三种格式的配置文件共存时
–优先级??

–三种格式的配置文件

–共存叠加:优先级低的有的 在 优先级高的中没有,那么都生效
–相互覆盖:优先级高的有的 覆盖 优先级低中有的
–优先级:properties>yml>yaml
–可以扔小黑屋 (bak包 -备份文件)
4.3 属性提示消失
–有的idea版本,可能在yml文件中提示属性自动补全


4.3 yaml文件–数据

4.3.1 语法规则

4.3.2数据格式 --SpEL表达式




–对象数组也可以这样写


4.4 yaml文件 --数据读取
4.4.1 读取yml单一属性数据

4.4.1.1 普通数据



4.4.1.2 对象属性



4.4.1.3 数组



4.4.2 yaml中的变量引用

–要是能引用就好了

–使用${}引用


4.4.3 转义字符
–比较特殊,与Java不相反
–\t并不会直接解析成 空格
–使用引号包裹的字符串,其中的转义字符可以生效

4.4.4 读取yml全部属性数据
4.4.4.1 全部封装
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yfdUXKEA-1692968930976)(E:\文档\后端\SpringBoot\SpringBoot入门笔记\asset\image-20221107112150785.png)]



4.4.4.2 精准封装(主流方式)
–也是springboot现有技术内部读取数据的主流方式 --部分封装
–需要什么封装什么,不要一股脑把所有数据封装到一个Environment对象中


–自定义对象封装指定数据

–调用这个类,创建对象


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SUTBxqe3-1692968930982)(E:\文档\后端\SpringBoot\SpringBoot入门笔记\asset\image-20221107114759307.png)]
5.基于SpringBoot实现SSMP整合
–整合第三方技术
–勾选依赖/手动导入依赖(starter)
–配置

5.1 整合Junit
–由于是maven工程,默认执行test,自带junit


–直接使用即可



5.2 Junit --classes属性

–如果测试类在引导类的当前包或者子包下,没问题
–一旦更改就会报错,测试类找不到引导类

–解决办法:

2.(不会这么写)

5.3 整合mybatis

–整合思想

–具体操作



–pom.xml

–配置相关信息

# 配置相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
username: root
password: root
–实体类(lombok)
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

–数据层

–测试


5.4 boot整合mybatis常见问题
–企业里boot版本 2.3.9 和 2.4.1使用的比较多
–老版本整合mybatis按照如上操作,会出现一点小问题

5.5 整合MyBatisPlus

–mybatisplus 又称 mp
–与mybatis的差异

–由于mybatisplus是国人开发的,并没有被spring给收录
那么两种创建工程办法:
–1.使用阿里云镜像创建
–2.手动添加
–搜索mybatisplus的依赖
https://mvnrepository.com/


<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
–实体类

–数据层


mp识别表名问题
–springboot在sql中判断表名是依据继承类的泛型,也就是BaseMapper的实体类Game
–解决办法
–设置表前缀


5.6 整合Druid
–spring没有收录,阿里云也没有,手工添加依赖
https://mvnrepository.com/

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
–配置
–第一种,可以使用,但不是标准的整合方式

–第二种,主流方式

# 配置相关信息
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
username: root
password: root
6.入门案例 -基于SpringBoot的SSMP整合

6.1 创建模块
–boot工程,勾选依赖项

–刷新maven(好习惯)
–pom.xml

–配置端口,application.yml

6.2 创建数据库
create database ssmp_db;
use ssmp_db;
create table tbl_book(
id int primary key auto_increment,
type varchar(20),
name varchar(20),
description varchar(100)
);
6.3 实体类快速开发(lombok)
–idea安装lombok插件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VLlgl1gE-1692968931000)(https://i0.hdslb.com/bfs/album/33c86ce9c470a4a38ac3c6dc8516a77f23e71f25.png)]
–导入lombook坐标
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
–提供了大量的注解快速开发实体类
–@Getter、@Setter
–@Data:有getter、setter、toString、hashCode、equals等等,唯独没有构造方法
–@AllArgsConstructor:全参构造方法
–@NoArgsConstructor:无参构造方法

–maven 编译,发现帮我们完成了很多代码

6.4 数据层标准开发

–导入Mybatisplus、druid坐标
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
–配置mybatisPlus 和druid
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5OiX6s37-1692968931003)(https://i0.hdslb.com/bfs/album/96a53a82288aff0ef6eee0adaf21bcaf70b41fb2.png)]
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssmp_db?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
username: root
password: root
–配置mybatisplus识别表前缀

–由于表名前习惯tbl_
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
–mybatisplus的id自增用的是雪花算法,与mysql的有所不同,需要自己设置,删除功能需要

–BookMapper
@Mapper
public interface BookMapper extends BaseMapper<Book> {
}
–测试BookMapper接口
@SpringBootTest
public class BookMapperTestCase {
@Autowired
private BookMapper bookMapper;
@Test
void testSelectById(){
System.out.println(bookMapper.selectById(1));
}
@Test
void testSave(){
Book book = new Book();
book.setType("测试1");
book.setName("测试1");
book.setDescription("测试1");
bookMapper.insert(book);
}
@Test
void testDelete(){
Book book = new Book();
book.setId(1);// 需要指定id
book.setType("测试1a");
book.setName("测试1");
book.setDescription("测试1");
bookMapper.updateById(book);
}
@Test
void testUpdate(){
bookMapper.deleteById(1);
}
@Test
void testSelectAll(){
bookMapper.selectList(null);// 必须给参数,随便写个参数就行
}
/**
* 分页功能
*/
@Test
void testGetPage(){
}
/**
* 根据条件查询
*/
@Test
void testSelectBy(){
}
}
6.5 开启MP运行日志
–开启日志后,就不需要打印语句了


–application.yml配置文件
server:
port: 8183
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssmp_db?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
username: root
password: root
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

6.6 分页
–1.Ipage对象
–2.手写一个MP插件(配置类)
–MP开启分页就是在sql语句后追加limit,但是需要手动开启分页功能
–并不是写配置,而是使用MP拦截器
–拦截器要受spring管理,要使用spring管理第三方bean的方式初始化bean并加载给spring
–MyBatis Plus自带分页插件(即BaseMapper接口中的selectPage()方法),只要简单的配置即可实现分页功能
–测试类
/**
* 分页功能
*/
@Test
void testGetPage(){
IPage page = new Page(1,5);
bookMapper.selectPage(page,null);
}
–MPConfig配置类
@Configuration
public class MPConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//创建总拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//总拦截器中添加内置拦截器001,001中开启分页功能
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xIlKIKgv-1692968931006)(https://i0.hdslb.com/bfs/album/e292357aacb73b57f1314c912ccf3eae2d6afbc9.png)]
–程序员怎么拿到分页中的各种数据呢?
–数据全部存在Ipage对象中
@Test
void testGetPage(){
IPage page = new Page(1,5);
bookMapper.selectPage(page,null);
System.out.println(page.getPages());//总页数
System.out.println(page.getCurrent());//当前第几页
System.out.println(page.getRecords());//本页数据映射对象
System.out.println(page.getSize());//一页展示几行
System.out.println(page.getTotal());//总共多少数据
System.out.println(page.getClass());//Ipage对象类路径
}

6.7 条件查询 -queryWrapper
–与分页一样,就是将sql操作转换成java API操作
–以模糊查询like举例,其他的类似操作自己拿捏

/**
* 根据条件查询
*/
@Test
void testSelectBy(){
QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name","测试");//根据列 与 属性名 模糊查询
bookMapper.selectList(queryWrapper);
}

6.7.1 改进写法(主流)
–上面这种列名字符串 "name"有可能写错,比如anme
–换一种写法,避免这种错误
@Test
void testSelectBy2(){
String name = null;
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
lqw.like(name != null,Book::getName,name);//参数一是判断是否为空,如果是null则不进行查询
bookMapper.selectList(lqw);
}
6.8 业务层标准开发

—BookService接口
public interface BookService {
Boolean save(Book book);
Boolean delete(Integer id);
Boolean update(Book book);
Book selectById(Integer id);
List<Book> selectAll();
IPage<Book> getPage(int currentPage, int pageSize);
}
—BookServiceImpl实现类
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookMapper bookMapper;
@Override
public Boolean save(Book book) {
return bookMapper.insert(book) > 0;//返回结果是影响行数
}
@Override
public Boolean delete(Integer id) {
return bookMapper.deleteById(id) > 0;
}
@Override
public Boolean update(Book book) {
return bookMapper.updateById(book) > 0;
}
@Override
public Book selectById(Integer id) {
return bookMapper.selectById(id);
}
@Override
public List<Book> selectAll() {
return bookMapper.selectList(null);
}
@Override
public IPage<Book> getPage(int currentPage, int pageSize) {
IPage<Book> page = new Page<>(currentPage,pageSize);
return bookMapper.selectPage(page,null);
}
}
–测试类
@SpringBootTest
public class BookServiceTestCase {
@Autowired
private BookService bookService;
@Test
void testGetById() {
System.out.println(bookService.selectById(1));
}
@Test
void testSave() {
Book book = new Book();
book.setType("测试数据123");
book.setName("测试数据123");
book.setDescription("测试数据123");
bookService.save(book);
}
@Test
void testUpdate() {
Book book = new Book();
book.setId(18);
book.setType("测试数据abcdefg");
book.setName("测试数据123");
book.setDescription("测试数据123");
bookService.update(book);
}
@Test
void testDelete() {
bookService.delete(16);
}
@Test
void testGetAll() {
bookService.selectAll();
}
@Test
void testGetPage() {
IPage<Book> page = bookService.getPage(2, 5);
System.out.println(page.getCurrent());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.getPages());
System.out.println(page.getRecords());
}
}
6.9 业务层快速开发
–MP提供了业务层快速开发,提供了通用功能
–业务层接口首字母加个 "I"是中规范


–IBookService接口,分页功能自己写
public interface IBookService extends IService<Book> {
IPage<Book> getPage(int currentPage, int pageSize);
}
–BookServiceImpl实现类,分页功能自己写
@Service
public class BookServiceImpl2 extends ServiceImpl<BookMapper, Book> implements IBookService {
@Autowired
private BookMapper bookMapper;
@Override
public IPage<Book> getPage(int currentPage, int pageSize) {
IPage<Book> page = new Page<>(currentPage, pageSize);
bookMapper.selectPage(page,null);
return page;
}
}
6.9.1 测试类测试业务层
–注意MP封装的方法名,重新写测试用例
@SpringBootTest
public class BookServiceTestCase {
@Autowired
private IBookService bookService;
@Test
void testGetById() {
System.out.println(bookService.getById(1));
}
@Test
void testSave() {
Book book = new Book();
book.setType("测试数据123");
book.setName("测试数据123");
book.setDescription("测试数据123");
bookService.save(book);
}
@Test
void testUpdate() {
Book book = new Book();
book.setId(18);
book.setType("测试数据abcdefg");
book.setName("测试数据123");
book.setDescription("测试数据123");
bookService.updateById(book);
}
@Test
void testDelete() {
bookService.removeById(16);
}
@Test
void testGetAll() {
bookService.list();
}
@Test
void testGetPage() {
IPage<Book> page = new Page<>(2,5);
bookService.page(page);
System.out.println(page.getCurrent());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.getPages());
System.out.println(page.getRecords());
}
}
–通用方法不能满足业务,则自定义方法

6.10 表现层标准开发
6.10.1 增删改查
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tQ0RBrqD-1692968931010)(https://i0.hdslb.com/bfs/album/3b7b442263e5b3f27dc3b190b80b1a9f6ccbb7f1.png)]
–BookController
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private IBookService bookService;
@GetMapping
public List<Book> getAll(){
return bookService.list();
}
@PostMapping
public Boolean save(@RequestBody Book book){
return bookService.save(book);
}
@PutMapping
public Boolean update(@RequestBody Book book){
return bookService.updateById(book);
}
@DeleteMapping("/{id}")
public Boolean delete(@PathVariable Integer id){
return bookService.removeById(id);
}
@GetMapping("/{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById(id);
}
}
6.10.2 apiPost测试表现层
–查全部
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4h4kWXXE-1692968931011)(https://i0.hdslb.com/bfs/album/58b8faedb74cbab936cbfd8a2d093d20143c16de.png)]
–查单个
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cmxdNZ3p-1692968931011)(https://i0.hdslb.com/bfs/album/4e82e2d9fad1844ea9c041a17d7d190e64654100.png)]
–增加
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pW22oP83-1692968931012)(https://i0.hdslb.com/bfs/album/5b0eb1d69f075c3a54aa299818c0c8ea7c4ec687.png)]
–删除
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AyaCpuBg-1692968931013)(https://i0.hdslb.com/bfs/album/a1ebf554b309e303eedc0bd71ac9d6f76b9922e0.png)]
–更新
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iDVUtaaB-1692968931014)(https://i0.hdslb.com/bfs/album/0fd367fe1031429be3f3fdcdcf0727377ff45ed7.png)]
6.10.3 分页
–BookController
@GetMapping("/{currentPage}/{pageSize}")
public IPage<Book> getPage(@PathVariable int currentPage, @PathVariable int pageSize){
return bookService.getPage(currentPage,pageSize);
}
–测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQMuTm2k-1692968931014)(https://i0.hdslb.com/bfs/album/305ad03dd8df282ddb26149298a05ee48c3d093a.png)]
6.10.4 前后端数据格式一致
–表现层前后端数据格式一致性
–Result返回结果类(R对象)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2k3WXr5O-1692968931016)(https://i0.hdslb.com/bfs/album/da52a2566d40184dff559a3d5a8459489400a6eb.png)]
@Data
public class Result {
private Boolean flag;
private Object data;
public Result(){}
public Result(Boolean flag){
this.flag = flag;
}
public Result(Boolean flag, Object data){
this.flag = flag;
this.data = data;
}
}
–BookController
@RestController
@RequestMapping("/books")
public class BookController2 {
@Autowired
private IBookService bookService;
@GetMapping
public Result getAll(){
return new Result(true,bookService.list());
}
@PostMapping
public Result save(@RequestBody Book book){
return new Result(bookService.save(book));
}
@PutMapping
public Result update(@RequestBody Book book){
return new Result(bookService.updateById(book));
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id){
return new Result(bookService.removeById(id));
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id){
return new Result(true,bookService.getById(id));
}
@GetMapping("/{currentPage}/{pageSize}")
public Result getPage(@PathVariable int currentPage, @PathVariable int pageSize){
return new Result(true,bookService.getPage(currentPage,pageSize));
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2GHkGg4-1692968931017)(https://i0.hdslb.com/bfs/album/4c8bc19b376048743d2fdaa4407921fb60dee1ab.png)]
6.10.5 前后端协议联调(axios发送异步请求)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gC1O3KY0-1692968931018)(https://i0.hdslb.com/bfs/album/9a4ad4a9ad434daf0161e59141799ba50d843de2.png)]
–引入前端页面




运维篇
1.工程打包与运行
1.1 win版
1.1.1 打包



1.1.2 运行



1.2 linux版
;
}
@PostMapping
public Result save(@RequestBody Book book){
return new Result(bookService.save(book));
}
@PutMapping
public Result update(@RequestBody Book book){
return new Result(bookService.updateById(book));
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id){
return new Result(bookService.removeById(id));
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id){
return new Result(true,bookService.getById(id));
}
@GetMapping("/{currentPage}/{pageSize}")
public Result getPage(@PathVariable int currentPage, @PathVariable int pageSize){
return new Result(true,bookService.getPage(currentPage,pageSize));
}
}
[外链图片转存中...(img-a2GHkGg4-1692968931017)]
#### 6.10.5 前后端协议联调(axios发送异步请求)
[外链图片转存中...(img-gC1O3KY0-1692968931018)]
--引入前端页面
[外链图片转存中...(img-6wfaESGG-1692968931018)]
[外链图片转存中...(img-peTBS9Cw-1692968931019)]
[外链图片转存中...(img-XMXr2AvP-1692968931020)]
[外链图片转存中...(img-Z6P0pEMG-1692968931020)]
# 运维篇
## 1.工程打包与运行
### 1.1 win版
#### 1.1.1 打包
[外链图片转存中...(img-dtQy5Z2u-1692968931021)]
[外链图片转存中...(img-DJDxgHjQ-1692968931022)]
[外链图片转存中...(img-hqmZKNn1-1692968931022)]
#### 1.1.2 运行
[外链图片转存中...(img-dLmnTdg9-1692968931023)]
[外链图片转存中...(img-nbi1HOTq-1692968931024)]
[外链图片转存中...(img-YPwSF0tI-1692968931024)]
### 1.2 linux版
316

被折叠的 条评论
为什么被折叠?



