在编写后台时,我们仍然假设前台尚未开发或前台的开发尚未完成。那么此时接口文档便是我们开发的唯一参考:
## GET 获取某个班级
使用JPA根据关键字来获取数据特别简单,在此直接给代码:
controller/KlassController.java
```
@GetMapping("{id}")
@ResponseStatus(HttpStatus.OK) ➊
public Klass get(@PathVariable Long id) {
return this.klassRepository.findById(id).get(); ➋
}
```
* ➊ OK(200, "OK") = 返回状态码200,对应的描述为"OK"。如果方法未使用@ResponseStatus进行注解,则表示默认返回HttpStatus.OK。所以此注解可省略。
* ➋ 使用`findById`方法来尝试获取数据表中的某个数据,如果该方法调用后成功获取到了数据,则可继续使用`get`方法来获取这个数据。
> 使用`findById`也是可能获取不到数据表中的值的,比如当ID为-1时则无法在数据表中找到id为-1的班级信息,此时继续调用`get`方法便会发生错误。
## PUT
先Thinking再Coding,在`JPA`中我们在更新数据的一般思想如下:
![](https://img.kancloud.cn/76/e8/76e8a775d46aa507f1c54566d0c381e9_172x242.png)
具体在当前更新班级的操作为:
controller/KlassController.java
```
/**
* 更新班级
* 获取数据库中的老数据
* 使用传入的新数据对老数据的更新字段赋值
* 将更新后的老数据重新保存在数据表中
* @param id 要更新的班级ID
* @param klass 新班级数据
*/
@PutMapping("{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void update(@PathVariable Long id, @RequestBody Klass klass) {
}
```
* ➊ NO_CONTENT(204, "No Content") The 204 (No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
## Coding
controller/KlassController.java
```
@PutMapping("{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void update(@PathVariable Long id, @RequestBody Klass klass) {
Klass oldKlass = klassRepository.findById(id).get(); ➊
oldKlass.setName(klass.getName()); ➋
oldKlass.setTeacher(klass.getTeacher()); ➌
klassRepository.save(oldKlass); ➍
}
```
* ➊
* ➋ 用传入的klass中的值来更新预更新字段。
* ➌ JPA会根据相关实体的关键字的值来设置数据表中的做为外键的值。比如Teacher的关键字为id,则JPA会根据klass中的teacher中的id来尝试设置`klass`数据表中的`teacher_id`的值。
* ➍ 更新操作与插入操作在JPA中均调用save方法,该方法会根据情景生成对应正确的sql语句来操作数据库。
## 测试
我们启动数据库后启动项目,首先在数据表中添加两条教师测试信息、一条班级测试信息。
![](https://img.kancloud.cn/fd/95/fd95d9e3d57d5ae8753f816ac7916bdf_573x140.png)
![](https://img.kancloud.cn/ad/ec/adeccbf89c619b29a469ff47638cfb91_459x121.png)
然后分别进行测试:
### GET
测试代码:
```
GET http://localhost:8080/Klass/1
```
测试结果:
```
GET http://localhost:8080/Klass/1
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 07 Nov 2019 06:57:27 GMT
{
"id": 1,
"teacher": {
"id": 1,
"name": "张喜硕",
"sex": false,
"username": "zhangxishuo",
"email": "zhangxishuo@yunzhiclub.com",
"createTime": null,
"updateTime": null
},
"name": "测试班级"
}
Response code: 200; Time: 282ms; Content length: 164 bytes
```
### PUT
测试代码:
```
PUT http://localhost:8080/Klass/1
Content-Type: application/json;charset=UTF-8;
{
"name": "更新测试班级",
"teacher": {
"id": 2
}
}
```
测试结果:
```
PUT http://localhost:8080/Klass/1
HTTP/1.1 204
Date: Thu, 07 Nov 2019 06:58:48 GMT
<Response body is empty>
Response code: 204; Time: 79ms; Content length: 0 bytes
```
验证:
![](https://img.kancloud.cn/98/2f/982fc7c81f52a0cf2c3469e6e8cc7c5b_419x126.png)
# 参考文档
| 名称 | 链接 | 预计学习时长(分) |
| --- | --- | --- |
| 源码地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step3.4.5](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step3.4.5) | - |
| saving-entites | [https://docs.spring.io/spring-data/jpa/docs/2.2.1.RELEASE/reference/html/#jpa.entity-persistence.saving-entites](https://docs.spring.io/spring-data/jpa/docs/2.2.1.RELEASE/reference/html/#jpa.entity-persistence.saving-entites) | 10 |
| CrudRepository | [https://docs.spring.io/spring-data/jpa/docs/2.2.1.RELEASE/reference/html/#repositories.core-concepts](https://docs.spring.io/spring-data/jpa/docs/2.2.1.RELEASE/reference/html/#repositories.core-concepts) | 10 |
- 序言
- 第一章:Hello World
- 第一节:Angular准备工作
- 1 Node.js
- 2 npm
- 3 WebStorm
- 第二节:Hello Angular
- 第三节:Spring Boot准备工作
- 1 JDK
- 2 MAVEN
- 3 IDEA
- 第四节:Hello Spring Boot
- 1 Spring Initializr
- 2 Hello Spring Boot!
- 3 maven国内源配置
- 4 package与import
- 第五节:Hello Spring Boot + Angular
- 1 依赖注入【前】
- 2 HttpClient获取数据【前】
- 3 数据绑定【前】
- 4 回调函数【选学】
- 第二章 教师管理
- 第一节 数据库初始化
- 第二节 CRUD之R查数据
- 1 原型初始化【前】
- 2 连接数据库【后】
- 3 使用JDBC读取数据【后】
- 4 前后台对接
- 5 ng-if【前】
- 6 日期管道【前】
- 第三节 CRUD之C增数据
- 1 新建组件并映射路由【前】
- 2 模板驱动表单【前】
- 3 httpClient post请求【前】
- 4 保存数据【后】
- 5 组件间调用【前】
- 第四节 CRUD之U改数据
- 1 路由参数【前】
- 2 请求映射【后】
- 3 前后台对接【前】
- 4 更新数据【前】
- 5 更新某个教师【后】
- 6 路由器链接【前】
- 7 观察者模式【前】
- 第五节 CRUD之D删数据
- 1 绑定到用户输入事件【前】
- 2 删除某个教师【后】
- 第六节 代码重构
- 1 文件夹化【前】
- 2 优化交互体验【前】
- 3 相对与绝对地址【前】
- 第三章 班级管理
- 第一节 JPA初始化数据表
- 第二节 班级列表
- 1 新建模块【前】
- 2 初识单元测试【前】
- 3 初始化原型【前】
- 4 面向对象【前】
- 5 测试HTTP请求【前】
- 6 测试INPUT【前】
- 7 测试BUTTON【前】
- 8 @RequestParam【后】
- 9 Repository【后】
- 10 前后台对接【前】
- 第三节 新增班级
- 1 初始化【前】
- 2 响应式表单【前】
- 3 测试POST请求【前】
- 4 JPA插入数据【后】
- 5 单元测试【后】
- 6 惰性加载【前】
- 7 对接【前】
- 第四节 编辑班级
- 1 FormGroup【前】
- 2 x、[x]、{{x}}与(x)【前】
- 3 模拟路由服务【前】
- 4 测试间谍spy【前】
- 5 使用JPA更新数据【后】
- 6 分层开发【后】
- 7 前后台对接
- 8 深入imports【前】
- 9 深入exports【前】
- 第五节 选择教师组件
- 1 初始化【前】
- 2 动态数据绑定【前】
- 3 初识泛型
- 4 @Output()【前】
- 5 @Input()【前】
- 6 再识单元测试【前】
- 7 其它问题
- 第六节 删除班级
- 1 TDD【前】
- 2 TDD【后】
- 3 前后台对接
- 第四章 学生管理
- 第一节 引入Bootstrap【前】
- 第二节 NAV导航组件【前】
- 1 初始化
- 2 Bootstrap格式化
- 3 RouterLinkActive
- 第三节 footer组件【前】
- 第四节 欢迎界面【前】
- 第五节 新增学生
- 1 初始化【前】
- 2 选择班级组件【前】
- 3 复用选择组件【前】
- 4 完善功能【前】
- 5 MVC【前】
- 6 非NULL校验【后】
- 7 唯一性校验【后】
- 8 @PrePersist【后】
- 9 CM层开发【后】
- 10 集成测试
- 第六节 学生列表
- 1 分页【后】
- 2 HashMap与LinkedHashMap
- 3 初识综合查询【后】
- 4 综合查询进阶【后】
- 5 小试综合查询【后】
- 6 初始化【前】
- 7 M层【前】
- 8 单元测试与分页【前】
- 9 单选与多选【前】
- 10 集成测试
- 第七节 编辑学生
- 1 初始化【前】
- 2 嵌套组件测试【前】
- 3 功能开发【前】
- 4 JsonPath【后】
- 5 spyOn【后】
- 6 集成测试
- 7 @Input 异步传值【前】
- 8 值传递与引入传递
- 9 @PreUpdate【后】
- 10 表单验证【前】
- 第八节 删除学生
- 1 CSS选择器【前】
- 2 confirm【前】
- 3 功能开发与测试【后】
- 4 集成测试
- 5 定制提示框【前】
- 6 引入图标库【前】
- 第九节 集成测试
- 第五章 登录与注销
- 第一节:普通登录
- 1 原型【前】
- 2 功能设计【前】
- 3 功能设计【后】
- 4 应用登录组件【前】
- 5 注销【前】
- 6 保留登录状态【前】
- 第二节:你是谁
- 1 过滤器【后】
- 2 令牌机制【后】
- 3 装饰器模式【后】
- 4 拦截器【前】
- 5 RxJS操作符【前】
- 6 用户登录与注销【后】
- 7 个人中心【前】
- 8 拦截器【后】
- 9 集成测试
- 10 单例模式
- 第六章 课程管理
- 第一节 新增课程
- 1 初始化【前】
- 2 嵌套组件测试【前】
- 3 async管道【前】
- 4 优雅的测试【前】
- 5 功能开发【前】
- 6 实体监听器【后】
- 7 @ManyToMany【后】
- 8 集成测试【前】
- 9 异步验证器【前】
- 10 详解CORS【前】
- 第二节 课程列表
- 第三节 果断
- 1 初始化【前】
- 2 分页组件【前】
- 2 分页组件【前】
- 3 综合查询【前】
- 4 综合查询【后】
- 4 综合查询【后】
- 第节 班级列表
- 第节 教师列表
- 第节 编辑课程
- TODO返回机制【前】
- 4 弹出框组件【前】
- 5 多路由出口【前】
- 第节 删除课程
- 第七章 权限管理
- 第一节 AOP
- 总结
- 开发规范
- 备用