文章目录

  • 项目实例
  • 一、开发
  • 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