1. Git创建项目
从Gitee中创建初始仓库。
通过IDEA创建SpringBoot Initializr项目。

这里使用aliyun的Spring Boot创建器,速度快还能使用阿里云的微服务的相关模块。在IDEA菜单中,创建一个本地git仓库。
VCS –> Import Into Version Control –> Create Git Repository
选择项目文件夹,会在项目文件夹下生成一个.git文件夹。修改:VCS –> Git –> Remotes

将其改为Git的地址,我这里用的是Gitee的仓库。

修改.gitignore文件,忽略无关的文件。这里使用.ignore插件来进行的。
安装插件后,在项目上右键点击新建文件:

选择这个Git忽略文件。在弹出窗口中选择相应的应该忽略的文件。这里加了Java和IDEA还有Maven的。

添加了之后确定就行了。如果有原来的.gitignore文件,会自动加到里面去。
之后将其他的没有忽略的文件,右键菜单,Git–>Add,添加到Git版本控制中。Commit,Push即可。
但是我Push的时候出现了错误。
Push rejected
Push to origin/master was rejected这个错误是因为:因为本地仓库和远程仓库的代码不一样
Gitee上初始创建的项目仓库,和本地的项目仓库并不一样。所以说先检出一下。
但是检出也出错了。

下午 8:37 Can’t Update
No tracked branch configured for branch master or the branch doesn't exist. To make your branch track a remote branch call, for example, git branch --set-upstream-to=origin/master master (show balloon)下午 8:37 Update canceled
按照提示,执行: git branch --set-upstream-to=origin/master master
这个命令的意思是,上传的代码中的origin或者master分支,设为仓库中的master分支。(origin/master是个“或者”,选项,所以说不能直接输入。。)
执行git push –set-upstream origin master
还是报错。
- 爷不演了,反正远程仓库里面并没有什么东西,是新建的一个仓库,暴力点,直接强制Push:
git push origin master -f。这个命令会强制把本地的Push到仓库中。这样会将本地的项目,将远程仓库中的完全覆盖。
2. 项目架构
2.1父项目
修改pom.xml文件
这里要用父子项目结构,所以说首先在<artifactId>节点后面添加 pom类型1
2<artifactId>guli_parent3</artifactId>
<packaging>pom</packaging>并且增加一个继承spring-boot-starter的parent节点:
1
2
3
4
5
6<!--添加partent标签,上面继承SpringBoot启动器-->
<parent>
<groupId>org.springframework.boot</groupId>
<version>2.2.1.RELEASE</version>
<artifactId>spring-boot-starter-parent</artifactId>
</parent>替换掉properties下的版本控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.2.1.RELEASE</spring-boot.version>
<guli.version>0.0.1-SNAPSHOT</guli.version>
<mybatis-plus.version>3.0.5</mybatis-plus.version>
<velocity.version>2.0</velocity.version>
<swagger.version>2.7.0</swagger.version>
<aliyun.oss.version>2.8.3</aliyun.oss.version>
<jodatime.version>2.10.1</jodatime.version>
<poi.version>3.17</poi.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-io.version>2.6</commons-io.version>
<httpclient.version>4.5.1</httpclient.version>
<jwt.version>0.7.0</jwt.version>
<aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version>
<aliyun-sdk-oss.version>3.1.0</aliyun-sdk-oss.version>
<aliyun-java-sdk-vod.version>2.15.2</aliyun-java-sdk-vod.version>
<aliyun-java-vod-upload.version>1.4.13</aliyun-java-vod-upload.version>
<aliyun-sdk-vod-upload.version>1.4.11</aliyun-sdk-vod-upload.version>
<fastjson.version>1.2.28</fastjson.version>
<gson.version>2.8.6</gson.version>
<json.version>20170516</json.version>
<commons-dbutils.version>1.7</commons-dbutils.version>
<canal.client.version>1.1.0</canal.client.version>
<docker.image.prefix>zx</docker.image.prefix>
<cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version>
</properties>删除depentcys,替换dependencyMangment:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157<dependencyManagement>
<dependencies>
<!--Spring Cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--mybatis-plus 持久层-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- <!–aliyunOSS–>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun.oss</groupId>-->
<!-- <artifactId>aliyun-sdk-oss</artifactId>-->
<!-- <version>${aliyun.oss.version}</version>-->
<!-- </dependency>-->
<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime.version}</version>
</dependency>
<!--xls-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<!--xlsx-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!--aliyun-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun-sdk-oss.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-vod</artifactId>
<version>${aliyun-java-sdk-vod.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>aliyun-java-vod-upload</artifactId>-->
<!-- <version>${aliyun-java-vod-upload.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>aliyun-sdk-vod-upload</artifactId>-->
<!-- <version>${aliyun-sdk-vod-upload.version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>${commons-dbutils.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>${canal.client.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2.2子项目
新建子项目service
New –> Module,新建子项目。选择Maven工程。

修改pom打包方式:1
2<artifactId>service</artifactId>
<packaging>pom</packaging>增加依赖:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!--hystrix依赖,主要是用 @HystrixCommand -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--服务注册-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!--lombok用来简化实体类:需要安装lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--xls-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!--gson-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
导包之坑
阿里云maven镜像
2020年最新的阿里云的maven镜像库变了,修改一下。把原来的都删掉了。
1 | <mirror> |
父项目pom
修改springboot的版本为2.2.1.RELEASE。
首先,先把父项目pom里面的aliyun-skd-oss给注释了,因为写重复了一个
1 | <!-- <!–aliyunOSS–>--> |
之后,阿里云上传组件飘红,暂未解决。
1 | <dependency> |
子项目pom
提示几个unknow,给它写上特定版本。这里版本是根据IDEA提示随机添加的
1 | <dependency> |
这里mysql的版本改了一下,用了个比较新的,因为旧的mysql驱动是com.mysql.jdbc.Driver而新的是com.mysql.cj.jdbc.Driver,多了个cj,不太一样。
新建子项目service-edu

新建配置文件application.properties
1 | # 服务端口 |
在test文件夹下,新建Mybatis-Plus代码生成器:
1 | package com.songx64.eduservice; |
修改相关配置,主要是
- 生成路径,最好用绝对路径;
- 数据库连接的名字,用户名密码;
- 包名,author名
之后运行即可。会自动生成代码:

编辑Teacher的控制类,启动类
EduTeacherController
- 自动注入Service,@Autowired
- 编写查询函数,@GetMapping
1 | package com.songx64.eduservice.controller; |
EduConfig
创建配置类,扫描mapper。不加入的话mapper扫描不到可能会报错。
创建config包,com.songx64.eduservice.config
@MapperScan(包名)
1 | package com.songx64.eduservice.config; |
启动类
在Edu-Service根目录下添加启动类:
1 | package com.songx64.eduservice; |
报错:java.lang.ClassNotFoundException: org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter
报错解决:
版本问题解决
错误:springboot的各种包都找不到。
原因:在父配置文件中,少加了个标签:
1 | <parent> |
这个自然是从Springboot官方的parent节点继承spring-boot-starter,没有这个原来的各种starter都没有集成进去。
原来我的方式是在一个个的子模块中重新集成了springboot的starter,而不是继承过来的。
启动报错问题解决
错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘eduTeacherController’: Unsatisfied dependency expressed through field ‘eduTeacherService’;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘eduTeacherServiceImpl’: Unsatisfied dependency expressed through field ‘baseMapper’;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.songx64.eduservice.mapper.EduTeacherMapper’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
这个是说找不到eduTeacherServiceImpl,还有baseMapper。
原因:忘了在config类中添加@Configuration注解
1 | package com.songx64.eduservice.config; |
访问报错:

原因:用的https访问的。https://localhost:8001/eduservice/edu-teacher/findAll
解决:修改为http协议即可。http://localhost:8001/eduservice/edu-teacher/findAll
Swagger2
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
1.新建common模块

2.在common/pom.xml中引入相关模块
1 | <!--mybatis-plus--> |
3.新建SwaggerConfig配置类

1 | package com.songx64.servicebase.config; |
配置类中的信息显示在页面中:

4.引入service-base模块
去service模块中的pom文件,引入自己的service-base模块
1 | <!--引入自己写的service-base模块--> |
5.编写文档说明注解
EduTeacherController.java类中:
1 |
|
新增了一个deleteTeacherById方法,用来测试。
同时一些Swagger的注解:
6.测试
最终进行测试,访问http://localhost:8001/swagger-ui.html

错误记录
找不到同项目的包
因为找不到包,从而没能扫描到swaggerConfig,显示:

最终也没找到原因,只能用另外办法了:
在子项目中引入另一个子项目:
service-edu的pom.xml中,引入service_base模块
1 | <artifactId>service-edu</artifactId> |
swagger配置报错
太长的完整报错不贴了,主要就是:
org.springframework.beans.factory.BeanDefinitionStoreException:
Failed to process import candidates for configuration class [springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration];
nested exception is java.io.FileNotFoundException: class path resource [com/google/common/base/Supplier.class] cannot be opened because it does not exist
删除了service目录下的swagger依赖:
service的pom.xml中,删除:
1 | <dependency> |
相关知识
pom文件中的<scope>标签
对于scope=compile的情况(默认scope),
也就是说这个项目在编译,测试,运行阶段都需要这个artifact对应的jar包在classpath中。而对于scope=provided的情况,则可以认为这个provided是目标容器已经provide这个artifact。
换句话说,它只影响到编译,测试阶段。
在编译测试阶段,我们需要这个artifact对应的jar包在classpath中,
而在运行阶段,假定目标的容器(比如我们这里的liferay容器)已经提供了这个jar包,所以无需我们这个artifact对应的jar包了。
总之就是,provided不会把jar包打进去。
比如父级已经把这个包打进去了,在子项目中就可以用provided,子项目的包不会被打进去,这样就可以避免包冲突了。
08.统一结果返回
为啥
项目中我们会将响应封装成json返回,一般我们会将所有接口的数据格式统一, 使==前端(iOS Android, Web)==对数据的操作更一致、轻松。
也就是说,后端和显示是无关的。前端接受数据就可以。后端就是提供数据的。
一般会包含状态码、返回消息、数据这几部分内容。
在这里,我们定义统一结果:
1 | { |
咋整
- 在common下创建子模块common_utils,新建包com.songx64.commonutils
- 新建接口ResultCode:
1 | public interface ResultCode{ |
- 新建结果类R
1 |
|
- 构造函数私有化1
- 构造函数私有化2
- return this:链式编程,R.ok().data(XXX).message(XXX)
- Lombok支持链式编程,加注解@Accessors(chain=true)即可
咋用
引入模块,service,pom.xml
1
2
3
4
5<dependency>
<groupId>com.songx64</groupId>
<artifactId>common_utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>修改Controller里的方法,返回结果改为R
com\songx64\eduservice\controller\EduTeacherController.java1
运行,进入swagger查看
有个TODO,删除的地方有问题
后台讲师管理模块
1.分页查询
1.1 配置分页插件
com.songx64.eduservice.config.EduConfig类中,粘贴mybatis的config配置插件
1 | public class EduConfig { |
1.2 编写讲师分页查询接口的方法
主要过程就是:
- 新建一个Page对象
- 调用page方法查询到Page对象中
- 从Page对象中取出数据,返回
EduTeacherController类中的分页查询方法:
1 | /** |
- Page
pageTeacher = new Page<>(current, limit); //新建对象 - eduTeacherService.page(pageTeacher, null);//通过page方法查询,放入对象
- List
records = pageTeacher.getRecords();//得到数据List - Long total = pageTeacher.getTotal(); //total是总条数
2.条件分页查询
多条件分页查询

- 新建VO对象
- 新建查询方法(先写到Controller中,之后放到Service中)
- 查询方法中:
- 创建Page对象
- 构造QueryWrapper查询条件
- 调用page查询
- 返回结果
传入参数对象实现
1 | /* |

关于@RequestBody和@ResponseBody注解
- @ResponseBody是用来返回数据的,返回JSON格式的数据;
- @RequestBody是使用JSON来传递数据,把传过来的数据封装到对象中;
上面的方法如果要使用@ResponseBody注解的话,要改为Post方式进行请求,Get方式不行
1 |
|
这里要加上required=false,保证为空的时候也能传入;
改为@ResponeBody注解后,传入的是一个JSON字符串:

提醒:面试时候可能问问题“你用过什么注解”,这里最好不要说太基础的Controller之类的,可以提一嘴刚才这两个以及他们的区别之类的东西。
相关知识:关于VO和DTO
关于VO和DTO:https://blog.csdn.net/zjrbiancheng/article/details/6253232
- VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。
- DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。
VO与DTO的区别
大家可能会有个疑问(在笔者参与的项目中,很多程序员也有相同的疑惑):既然DTO是展示层与服务层之间传递数据的对象,为什么还需要一个VO呢?对!对于绝大部分的应用场景来说,DTO和VO的属性值基本是一致的,而且他们通常都是POJO,因此没必要多此一举,但不要忘记这是实现层面的思维,对于设计层面来说,概念上还是应该存在VO和DTO,因为两者有着本质的区别,DTO代表服务层需要接收的数据和返回的数据,而VO代表展示层需要显示的数据。
用一个例子来说明可能会比较容易理解:例如服务层有一个getUser的方法返回一个系统用户,其中有一个属性是gender(性别),对于服务层来说,它只从语义上定义:1-男性,2-女性,0-未指定,而对于展示层来说,它可能需要用“帅哥”代表男性,用“美女”代表女性,用“秘密”代表未指定。说到这里,可能你还会反驳,在服务层直接就返回“帅哥美女”不就行了吗?对于大部分应用来说,这不是问题,但设想一下,如果需求允许客户可以定制风格,而不同风格对于“性别”的表现方式不一样,又或者这个服务同时供多个客户端使用(不同门户),而不同的客户端对于表现层的要求有所不同,那么,问题就来了。再者,回到设计层面上分析,从职责单一原则来看,服务层只负责业务,与具体的表现形式无关,因此,它返回的DTO,不应该出现与表现形式的耦合。
理论归理论,这到底还是分析设计层面的思维,是否在实现层面必须这样做呢?一刀切的做法往往会得不偿失,下面我马上会分析应用中如何做出正确的选择。VO与DTO的应用
上面只是用了一个简单的例子来说明VO与DTO在概念上的区别,本节将会告诉你如何在应用中做出正确的选择。
在以下才场景中,我们可以考虑把VO与DTO二合为一(注意:是实现层面):
当需求非常清晰稳定,而且客户端很明确只有一个的时候,没有必要把VO和DTO区分开来,这时候VO可以退隐,用一个DTO即可,为什么是VO退隐而不是DTO?回到设计层面,服务层的职责依然不应该与展示层耦合,所以,对于前面的例子,你很容易理解,DTO对于“性别”来说,依然不能用“帅哥美女”,这个转换应该依赖于页面的脚本(如JavaScript)或其他机制(JSTL、EL、CSS)
即使客户端可以进行定制,或者存在多个不同的客户端,如果客户端能够用某种技术(脚本或其他机制)实现转换,同样可以让VO退隐以下场景需要优先考虑VO、DTO并存:
上述场景的反面场景
因为某种技术原因,比如某个框架(如Flex)提供自动把POJO转换为UI中某些Field时,可以考虑在实现层面定义出VO,这个权衡完全取决于使用框架的自动转换能力带来的开发和维护效率提升与设计多一个VO所多做的事情带来的开发和维护效率的下降之间的比对。
如果页面出现一个“大视图”,而组成这个大视图的所有数据需要调用多个服务,返回多个DTO来组装(当然,这同样可以通过服务层提供一次性返回一个大视图的DTO来取代,但在服务层提供一个这样的方法是否合适,需要在设计层面进行权衡)。
3.添加讲师
3.1 修改自动填充时间
1.实体类EduTeacher上面加注解@TableField,插入时和更新时填充
1 |
|
2.自定义实现接口功能,自动填充
封装至common模块,servicebase下,新建handler包,新建MyMetaObjectHandler类
1 | package com.songx64.servicebase.handler; |
这里大概就是通过@TableFiled注解,然后通过MyMetaObjectHandler处理填充值
Mybatis-Plus文档:https://baomidou.com/guide/auto-fill-metainfo.html
3.2 添加讲师方法
wdnmd,修改实体类之后Jrebel热部署不管用?
遇到问题:说是id字段的类型不匹配,dismatch。修改重启换版本之后,不用Jrebel运行而是用原来的运行,可以了就。草
1 | /* |
tmd为啥行了呢?为啥不行呢?
4.修改讲师
4.1 根据Id来查询讲师
这个没啥好说的,直接调用就完事了。不过要回忆一下这个@PathVariable注解。
1 | /* |
4.2 根据ID修改讲师
这里用了两种方式,一种Post请求,一种Put请求
Post请求方式
1 | /* |
Put请求方式
1 | /* |
相关知识:关于Put和Post
https://blog.csdn.net/qq_36183935/article/details/80570062
PUT和POST
PUT和POS都有更改指定URI的语义.但PUT被定义为idempotent的方法,POST则不是.idempotent的方法:如果一个方法重复执行
多次,产生的效果是一样的,那就是idempotent的。也就是说:
PUT请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源)
Post请求:后一个请求不会把第一个请求覆盖掉。(所以Post用来增资源)
https://www.zhihu.com/question/48482736
一个例子是网不好的时候,post提交后没收到响应,于是客户端再次尝试提交,成功后刷新看到新建了两条资源,如果用put的话就不会出现这样的情况。所以尽量使用put去代替post