文章目录
- 项目实例
- 一、开发
- 1.1 开发流程
- 1.2 开发规范-Restful
- 1.3 统一式响应结果
- 二、Spring boot三层架构
- 三、示例
- 3.1 实现示例(删除功能)
- ==接口文档==
- ==后端代码==
- 3.2 分页查询
- 3.2文件上传
项目实例
一、开发
1.1 开发流程
查看页面原型确定需求——阅读接口文档——思路分析——接口开发——接口测试——前后端联调
1.2 开发规范-Restful
REST(REpresentational State Transfer),表述性状态转换,是一种软件架构风格
REST风格
查询id为1的用户
http://localhost:8080/ugers/1 GET:查询id为1的用户
http://localhost:8080/users POST:新增用户
http://localhost:8080/users PUT:修改用户
http://localhost:8080/users/1 DELETE:删除id为1的用户
- URL定位资源
- HTTP动词描述操作
- REST是风格,是约定方式,约定不是规定,可以打破
- 描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。如:users、emps、books~
1.3 统一式响应结果
在项目中一般都会封装一个返回值类,来确保所有接口都返回固定的格式。
package whopxx.start.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应信息 描述字符串
private Object data; //返回的数据
//增删改 成功响应
public static Result success(){
return new Result(1,"success",null);
}
//查询 成功响应
public static Result success(Object data){
return new Result(1,"success",data);
}
//失败响应
public static Result error(String msg){
return new Result(0,msg,null);
}
}
二、Spring boot三层架构
pojo层(实体层)
一般数据库的一张表对应一个pojo层,并且表中所有字段都在pojo层都一一对应。
dao层、mapper层(数据持久层)
对数据库进行持久化操作,他的方法是针对数据库操作的,基本用到的就是增删改查。它只是个接口,只有方法名字,具体实现在mapper.xml中或者使用对应注解。
service层(业务逻辑层)
service层叫业务逻辑层,存放业务逻辑处理,不直接对数据库进行操作,有接口和接口实现类,提供controller层调用的方法。
创建两个文件,一个存放接口类,一个存放接口实现类。
controller层(控制器层)
controller层叫控制器层,负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。
三、示例
- 开发流程:明确需求 - 接口文档 - 思路分析 - 接口开发
- 接口调试:测试,前后端联调
3.1 实现示例(删除功能)
接口文档
基本信息
请求路径:/depts/{id}
请求方式:DELETE
接口描述:该接口用于根据ID删除部门数据
请求参数
参数格式:路径参数
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
id | number | 必须 | 部门ID |
请求参数样例:
/depts/1
响应数据
参数格式:application/json
参数说明:
参数名 | 类型 | 是否必须 | 备注 |
code | number | 必须 | 响应码,1 代表成功,0 代表失败 |
msg | string | 非必须 | 提示信息 |
data | object | 非必须 | 返回的数据 |
响应数据样例:
{
"code":1,
"msg":"success",
"data":null
}
后端代码
DeptController Controller层
@RestController
@Slf4j // 可以直接调用log
public class DeptController {
@Autowired
private DeptService deptService;
@DeleteMapping("/depts/{id}")
public Result delete(@PathVariable Integer id){
log.info("根据id删除部门:{}",id );
deptService.delete(id);
return Result.success();
}
}
DeptService Service层
public interface DeptService {
void delete(Integer id);
}
DeptServiceImpl Service实现层
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public void delete(Integer id) {
deptMapper.deleteById(id);
}
}
DeptMapper Mapper层
@Mapper
public interface DeptMapper {
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
}
3.2 分页查询
数据库语句
select count(*) from emp; -- 获取数据总数
select * from emp limit 起始索引,总数
EmpController Controller层
@RestController
@Slf4j
public class EmpController {
@Autowired
private EmpService empService;
@GetMapping("/emps")
public Result page(@RequestParam(defaultValue = "1") Integer page,
@RequestParam (defaultValue = "10") Integer pageSize,
String name, Short gender,
@DateTimeFormat(pattern = "yyyy-MM-dd")LocalDate begin,
@DateTimeFormat(pattern = "yyyy-MM-dd")LocalDate end){
log.info("分页查询:{},{}",page,pageSize);
PageBean pageBean = empService.page(page, pageSize,name,gender,begin,end);
return Result.success(pageBean);
}
}
EmpService Service层
public interface EmpService {
PageBean page(Integer page, Integer pageSize,String name, Short gender, LocalDate begin, LocalDate end);
}
EmpServiceImpl Service实现层
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end) {
Long count = empMapper.count();
List<Emp> list = empMapper.page((page - 1) * pageSize, pageSize,name,gender,begin,end);
return new PageBean(count,list);
}
}
EmpMapper Mapper层
@Mapper
public interface EmpMapper {
@Select("select count(*) from emp")
public Long count();
// @Select("select * from emp limit #{start},#{pageSize}")
public List<Emp> page(Integer start, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end)
}
XML映射
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="whopxx.start.mapper.EmpMapper">
<select id="page" resultType="whopxx.start.pojo.Emp">
select *
from emp
<where>
<if test="name != null and name != ''">
name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
</where>
order by update_time desc
limit #{start},#{pageSize}
</select>
</mapper>
PageHelper插件
3.2文件上传
MultipartFile常用方法
String getOriginalFilename(); // 获取原始文件名
void transferTo(File dest); // 将接收的文件转存到磁盘文件当中
long getSize(); // 获取文件的大小,单位:字节
byte[] getBytes(); // 获取文件内容的字节数组
InputStream getInputStream(); // 获取接收到的文件的内容的输入流
前端 :file表单项,post方式,multipart/form-data
如果是form表单的话,在form标签中加入 enctype=“multipart/form-data”
<form action="/upload" method="post" enctype="multipart/form-data">
姓名: <input type="text" name="username"><br>
年龄: <input type="text" name="age"><br>
头像: <input type="file" name="image"><br>
<input type="submit" value="提交">
</form>
后端 MultipartFile
本地存储 无法直接访问、磁盘空间限制、磁盘损坏
@RestController
@Slf4j
public class UploadController {
@PostMapping("/upload")
public Result upload(String username, Integer age, MultipartFile image) throws IOException {
log.info("文件上传:{} {} {} ",username,age,image);
// 获取文件后缀名
String fn = image.getOriginalFilename();
int index = fn.lastIndexOf(".");
// 构造唯一文件名 -- uuid(通用统一识别码)
String newFileName = UUID.randomUUID().toString() + fn.substring(index);;
// 将文件存储在服务器的磁盘目录中
image.transferTo(new File("C:\\Users\\HUAWEI\\Desktop\\javaweb\\files\\" + newFileName));
log.info("文件上传:{}",newFileName);
return Result.success();
}
}
默认的单个文件允许最大大小为1M。上传大文件可以增加下面配置:
# 配置单个文件上传大小限制
spring.servlet.multipart.max-file-size=10MB
# 配置单次请求文件大小限制
spring.servlet.multipart.max-request-size=100MB