请求响应

  • 请求(HttpServletRequest):获取请求数据
  • 响应(HttpServletResponse):设置响应数据
  • BS架构:Browser/Server,浏览器/服务器架构模式。客户端指需要浏览器,应用程序的逻辑和数据都存储在服务端
  • CS架构:Client/Server,客户端/服务器架构模式

image-20230731072631780

postman工具

postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件

作用:常用于进行接口测试

请求

  • 简单参数

    • 原始方式
      在原始的程序web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取

      1
      2
      3
      4
      5
      6
      7
      8
      @RequestMapping("simpleParam")
      public String simpleParam(HttpServletRequest request) {
      String name = request.getParameter("name");
      String ageStr = request.getParameter("ageStr");
      int age = Integer.parseInt(ageStr);
      System.out.println(name + " : " + age);
      return "OK";
      }
    • SpringBoot方式
      简单参数:如果方法形参名称与请求参数名称不匹配,可以使用 @RequestParam 完成映射

      1
      2
      3
      4
      5
      @RequestMapping("/simpleParam")
      public String simpleParam(@RequestParam(name = "name") String username, Integer age) {
      System.out.println(username + " : " + age);
      return "OK";
      }
  • 简单实体对象:请求参数名与形参对象属性名相同,定义POJO接收即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package com.zishuq.pojo;

    public class User {
    private String name;
    private Integer age;
    private Address address;
    }

    class Address {
    private String province;
    private String city;
    }
    1
    2
    3
    4
    5
    @RequestMapping("/complexPojo")
    public String complexPojo(User user) {
    System.out.println(user);
    return "OK";
    }
  • 数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数

    1
    2
    3
    4
    5
    @RequestMapping("/arrayParam")
    public String simplePojo(String[] hobby) {
    System.out.println(Arrays.toString(hobby));
    return "OK";
    }
  • 集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam绑定参数关系

    1
    2
    3
    4
    5
    @RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby) {
    System.out.println(hobby);
    return "OK";
    }
  • 日期参数:使用 @DateTimeFormat注解完成日期参数格式转换

    1
    2
    3
    4
    5
    @RequestMapping("/dateParam")
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")LocalDateTime updateTime) {
    System.out.println(updateTime);
    return "OK";
    }
  • JSON参数:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用 @RequestBody 标识

    1
    2
    3
    4
    5
    @RequestMapping("/jsonParam")
    public String jsonParam(@RequestBody User user) {
    System.out.println(user);
    return "OK";
    }

    数据:

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "name":"zishuQ",
    "age":20,
    "address":{
    "province":"北京",
    "city":"北京"
    }
    }
  • 路径参数:通过请求URL直接传递参数,使用{...}来标识该路径参数,需要使用 @PathVariable获取路径参数

    1
    2
    3
    4
    5
    @RequestMapping("/path/{id}/{name}")
    public String pathParam(@PathVariable Integer id, @PathVariable String name) {
    System.out.println(id + " : " + name);
    return "OK";
    }

响应

@ResponseBody

  • 类型:方法注解、类注解
  • 位置:Controller方式上/类上
  • 作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合,将会转换为JSON格式响应
  • 说明:@RestController = @Controller + @RTesponseBody

示例:

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
@RestController
public class ResponseController {

@RequestMapping("/hello")
public String hello() {
System.out.println("Hello World~");
return "Hello World~";
}

@RequestMapping("/getAddr")
public Address getAddr() {
Address addr = new Address();
addr.setProvince("山东");
addr.setCity("青岛");
return addr;
}

@RequestMapping("/listAddr")
public List<Address> listAddr() {
List<Address> list = new ArrayList<>();

Address addr = new Address();
addr.setProvince("山东");
addr.setCity("青岛");

Address addr2 = new Address();
addr2.setProvince("山东");
addr2.setCity("临沂");

list.add(addr);
list.add(addr2);
return list;
}
}

统一响应结果:

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
package com.zishuq.pojo;

public class Result {
private Integer code; // 1 成功, 0 失败
private String msg; // 提示信息
private Object data; // 数据 data

public Result() {
}

public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}

public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}

public static Result success(Object data) {
return new Result(1, "success", data);
}

public static Result success(String msg) {
return new Result(1, msg, null);
}

public static Result error() {
return new Result(1, "success", null);
}

@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
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
public class ResponseController {

@RequestMapping("/hello")
public Result hello() {
System.out.println("Hello World ~");
return Result.success("Hello World ~");
}

@RequestMapping("/getAddr")
public Result getAddr() {
Address addr = new Address();
addr.setProvince("山东");
addr.setCity("青岛");
return Result.success(addr);
}

@RequestMapping("/listAddr")
public Result listAddr() {
List<Address> list = new ArrayList<>();

Address addr = new Address();
addr.setProvince("山东");
addr.setCity("青岛");

Address addr2 = new Address();
addr2.setProvince("山东");
addr2.setCity("临沂");

list.add(addr);
list.add(addr2);
return Result.success(list);
}
}

分层解耦

  • 内聚:软件中各个功能模块内部的功能联系
  • 耦合:衡量软件中各个层/模块之间的依赖、关联的程度
  • 软件设计原则:高内聚低耦合

三层架构

  • controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据
  • service:业务逻辑层,处理具体的业务逻辑
  • dao:数据访问层(Data Access Object)(持久层),复制数据访问操作,包括数据的增、删、改、查

IOC-DI

  • 控制反转:Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转
  • 依赖注入:Dependency Injection,简称DI。容器为应用程序提供运行时所依赖的资源,称之为依赖注入
  • Bean对象:IOC容器中创建、管理的对象,称之为bean

步骤:

  1. Service层 及 Dao层的实现类,交给IOC容器管理 @Component

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Component
    public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
    // 1.从文件中查询数据
    String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
    List<Emp> empList = XmlParseUtils.parse(file, Emp.class);
    return empList;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Component
    public class EmpServiceA implements EmpService {

    private EmpDao empDao = new EmpDaoA();

    @Override
    public List<Emp> listEmp() {
    // 调用dao层,查询数据
    List<Emp> empList = empDao.listEmp();
    // ...
  2. 为Controller及Service注入运行时依赖的对象 @Autowired

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @RestController
    public class EmpController {
    @Autowired
    private EmpService empService;

    @RequestMapping("/listEmp")
    public Result listEmp() throws Exception {
    List<Emp> empList = empService.listEmp();
    return Result.success(empList);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Component
    public class EmpServiceA implements EmpService {
    @Autowired
    private EmpDao empDao = new EmpDaoA();

    @Override
    public List<Emp> listEmp() {
    // 调用dao层,查询数据
    List<Emp> empList = empDao.listEmp();
    // ...
  3. 运行测试

Bean的声明

注解 说明 位置
@Component 声明bean的基础注解 不属于以下三恶吏时,用此注解
@Controller @Component的衍生注解 标注在控制器类上
@Service @Component的衍生注解 标注在业务类上
@Repository @Component的衍生注解 标注在数据访问类上(由于与mybatis整合,用的少
  • 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写
  • 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller

Bean组件扫描

  • 前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描
  • @ComponentScan注解虽然没有显示配置,但是实际上已经包含在启动类声明注解@SpringBootApplication中,默认扫描的范围是启动类所在包及其子包

Bean注入

  • @Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报错

  • 通过以下几种方案来解决:

    • @Primary

      1
      2
      3
      @Primary
      @Service
      public class EmpServiceA implements EmpService{}
    • @Qualifier

      1
      2
      3
      4
      5
      @RestController
      public class EmpController {
      @Autowired
      @Qualifier("empServiceA")
      private EmpService empService;
    • @Resource

      1
      2
      3
      4
      @RestController
      public class EmpController {
      @Resource(name = "empServiceB")
      private EmpService empService;

      @Resouce 与 @Autowired区别

      • @Autowired 是spring框架提供的注解,而@Resource是JDK提到的注解

      • @Autowired 默认是按照类型注入,而@Resource默认是按照名称注入

数据库

  • 数据库:DataBase(DB),是存储和管理数据的仓库
  • 数据库管理系统:DataBase Management System(DBMS),操纵和管理数据库的大型软件
  • SQL:Structured Query Language,操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准

数据模型

  • 关系型数据库(RDBMS):建立在关系模型基础上,由多张相互连接的二维表组成的数据库。

    特点:

    使用表存储数据,格式统一,便于维护

    使用SQL语言操作,标准统一,使用方便,可用于复杂查询

SQL语句

SQL语句通常被分为四大类:

分类 全称 说明
DDL Data Definition Language 数据定义语言,用来定义数据库对象(数据库,表,字段)
DML Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改
DQL Data Query Language 数据查询语言,用来查询数据库中表的记录
DCL Data Control Language 数据控制语言,用来创建数据库用户、控制数据库的访问权限

数据库操作

查询

  • 查询所有数据库:show databases;
  • 查询当前数据库:select database();

使用

  • 使用数据库:use 数据库名;

创建

  • 创建数据库:create database [if not exists] 数据库名;

删除

  • 删除数据库:drop database [if exists] 数据库名;

表操作

创建

1
2
3
4
5
create table 表名(
字段1 字段类型 [约束] [comment 字段1注释],
...
字段n 字段类型 [约束] [comment 字段n注释],
)[comment 表注释]