1.声明式事务
1.1 新增问题的程序漏洞
如果在新增问题的业务逻辑层运行过程中发生了异常,就会导致问题可能新增完毕,但是问题和关系(标签、讲师)新增失败的情况,这样就可能出现一个问题没有关联任何标签,或者没有关联任何讲师的情况。这种情况是不好的,在企业开发过程中,必须避免这种情况的发生。因为这样会引发数据安全性问题,可能导致程序运行过程中发生异常,要想避免这个问题就需要使用到事务。
1.2 什么是事务?
定义:是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。
常见面试题
数据库事务的四个特性,简称ACID特性
-
原子性(Atomicity):事务作为一个整体被执行,事务中的操作要么都成功,要么都失败(要执行都执行,要不执行都不执行);
-
一致性(Consistency):事务运行前后,一致状态保持不变,例如:转账前后银行中的总金额不变;
-
隔离性(Isolation):数据库支持多个事务并发执行,互不干扰
-
持久性(Durability):已经提交的事务对数据库的影响是持久的,不可临时退回
1.3 Spring Boot 声明式事务
Spring Boot框架中整合了Spring事务的管理功能,允许在业务逻辑层方法上添加事务管理的注解,一旦添加该注解,此方法中的所有数据库操作被管理为一个事务,即要么都执行,要么都不执行,就能解决上面的问题了。在这个方法运行过程中,如果没有发生异常,事务中数据库的操作就会正常提交生效;如果发生了异常,该方法中所有数据库操作全部取消,回滚(恢复)为运行之前的状态。
在实现类QuestionServiceImpl的saveQuestion方法上添加@Transactional注解:
//新增用户发布的问题
为了安全起见,可以在前面接收注册表单数据的vo类RegisterVo上也加上事务管理的注解。
2.统一异常处理
2.1 为什么需要统一异常处理?
在注册和发布问题的控制层代码中,需要对业务逻辑层进行异常处理,这样的异常处理在以后的功能中会不断出现,这样异常处理的代码就会形成冗余,代码显得臃肿,不方便维护。
2.2 Spring Mvc的统一异常处理
由于开发过程中大多是由控制器承担异常处理的,所以SpringMvc框架提供了一套异常处理的机制,能够自动处理控制层中发生的各种异常,在控制层代码中就不需要编写try-catch了。我们只需要根据SpringMvc提供的格式编写一个类即可,在controller包中创建类ExceptionControllerAdvice,代码如下:
package cn.tedu.knows.portal.controller;
?
import cn.tedu.knows.portal.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//@RestControllerAdvice:表示当前类是给其他控制器类新增功能的
//我们这里的功能指异常处理
统一异常处理类运行流程:
3.文件上传
3.1 什么是文件上传?
即客户端将文件复制到服务器的过程,我们在static文件夹下创建一个可以上传文件的页面如下:upload.html
3.2 实现简单的同步上传
在SystemController类中添加如下方法:
测试效果:
(1)浏览器
(2)控制台
3.3 实现异步上传
修改upload.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上载演示</title>
<!--添加引用-->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<!--引入axios框架-->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js">
</script>
</head>
<body>
<form id="demoForm" ><!--删除demoForm后面的代码-->
<div>
<label>上传文件
<input id="imageFile" type="file" name="imageFile">
</label>
</div>
<button type="submit">上传文件</button>
</form>
<img id="image" src="" alt="">
<!--引入js文件-->
<script src="js/utils.js"></script>
<!--编写提交方法-->
<script>
$("#demoForm").submit(function(){
console.log("上传文件方法运行");
// 获得用户选中的文件(数组)
let files=document.getElementById("imageFile").files;
// 判断用户是否选择了文件
if(files.length>0){
//用户选中的文件执行上传
//我们单独编写一个方法执行上传
uploadImage(files[0]);//数组中的第一张图片
}else{
alert("请选择文件");
}
// 阻止表单提交
return false;
})
//上传文件的方法
function uploadImage(file){
// 构建表单
let form=new FormData();
form.append("imageFile",file);
// axios提交数据
}
?
</script>
</body>
</html>