SpringBootWeb案例
前面我們已經(jīng)講解了Web前端開發(fā)的基礎(chǔ)知識(shí),也講解了Web后端開發(fā)的基礎(chǔ)(HTTP協(xié)議、請(qǐng)求響應(yīng)),并且也講解了數(shù)據(jù)庫MySQL,以及通過Mybatis框架如何來完成數(shù)據(jù)庫的基本操作。 那接下來,我們就通過一個(gè)案例,來將前端開發(fā)、后端開發(fā)、數(shù)據(jù)庫整合起來。 而這個(gè)案例呢,就是我們前面提到的Tlias智能學(xué)習(xí)輔助系統(tǒng)。
在這個(gè)案例中,前端開發(fā)人員已經(jīng)將前端工程開發(fā)完畢了。 我們需要做的,就是參考接口文檔完成后端功能的開發(fā),然后結(jié)合前端工程進(jìn)行聯(lián)調(diào)測(cè)試即可。
完成后的成品效果展示:
今天的主要內(nèi)容如下:
- 準(zhǔn)備工作
- 部門管理
- 員工管理
下面我們就進(jìn)入到今天的第1個(gè)內(nèi)容準(zhǔn)備工作
的學(xué)習(xí)。
1. 準(zhǔn)備工作
準(zhǔn)備工作的學(xué)習(xí),我們先從"需求"和"環(huán)境搭建"開始入手。
1.1 需求&環(huán)境搭建
1.1.1 需求說明
1、部門管理
部門管理功能開發(fā)包括:
- 查詢部門列表
- 刪除部門
- 新增部門
- 修改部門
2、員工管理
員工管理功能開發(fā)包括:
- 查詢員工列表(分頁、條件)
- 刪除員工
- 新增員工
- 修改員工
1.1.2 環(huán)境搭建
步驟:
- 準(zhǔn)備數(shù)據(jù)庫表(dept、emp)
- 創(chuàng)建springboot工程,引入對(duì)應(yīng)的起步依賴(web、mybatis、mysql驅(qū)動(dòng)、lombok)
- 配置文件application.properties中引入mybatis的配置信息,準(zhǔn)備對(duì)應(yīng)的實(shí)體類
- 準(zhǔn)備對(duì)應(yīng)的Mapper、Service(接口、實(shí)現(xiàn)類)、Controller基礎(chǔ)結(jié)構(gòu)
第1步:準(zhǔn)備數(shù)據(jù)庫表
-- 部門管理
create table dept(
id int unsigned primary key auto_increment comment '主鍵ID',
name varchar(10) not null unique comment '部門名稱',
create_time datetime not null comment '創(chuàng)建時(shí)間',
update_time datetime not null comment '修改時(shí)間'
) comment '部門表';
-- 部門表測(cè)試數(shù)據(jù)
insert into dept (id, name, create_time, update_time) values(1,'學(xué)工部',now(),now()),(2,'教研部',now(),now()),(3,'咨詢部',now(),now()), (4,'就業(yè)部',now(),now()),(5,'人事部',now(),now());
-- 員工管理(帶約束)
create table emp (
id int unsigned primary key auto_increment comment 'ID',
username varchar(20) not null unique comment '用戶名',
password varchar(32) default '123456' comment '密碼',
name varchar(10) not null comment '姓名',
gender tinyint unsigned not null comment '性別, 說明: 1 男, 2 女',
image varchar(300) comment '圖像',
job tinyint unsigned comment '職位, 說明: 1 班主任,2 講師, 3 學(xué)工主管, 4 教研主管, 5 咨詢師',
entrydate date comment '入職時(shí)間',
dept_id int unsigned comment '部門ID',
create_time datetime not null comment '創(chuàng)建時(shí)間',
update_time datetime not null comment '修改時(shí)間'
) comment '員工表';
-- 員工表測(cè)試數(shù)據(jù)
INSERT INTO emp
(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
(1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
(2,'zhangwuji','123456','張無忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
(3,'yangxiao','123456','楊逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
(4,'weiyixiao','123456','韋一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
(5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
(6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
(7,'jixiaofu','123456','紀(jì)曉芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
(8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
(9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
(10,'zhaomin','123456','趙敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
(11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),
(12,'hebiweng','123456','鶴筆翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),
(13,'fangdongbai','123456','方東白',1,'13.jpg',5,'2012-11-01',3,now(),now()),
(14,'zhangsanfeng','123456','張三豐',1,'14.jpg',2,'2002-08-01',2,now(),now()),
(15,'yulianzhou','123456','俞蓮舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
(16,'songyuanqiao','123456','宋遠(yuǎn)橋',1,'16.jpg',2,'2007-01-01',2,now(),now()),
(17,'chenyouliang','123456','陳友諒',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
第2步:創(chuàng)建一個(gè)SpringBoot工程,選擇引入對(duì)應(yīng)的起步依賴(web、mybatis、mysql驅(qū)動(dòng)、lombok) (版本選擇2.7.5版本,可以創(chuàng)建完畢之后,在pom.xml文件中更改版本號(hào))
生成的pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/>
</parent>
<groupId>com.itheima</groupId>
<artifactId>tlias-web-management</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>tlias-web-management</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
創(chuàng)建項(xiàng)目工程目錄結(jié)構(gòu):
第3步:配置文件application.properties中引入mybatis的配置信息,準(zhǔn)備對(duì)應(yīng)的實(shí)體類
- application.properties (直接把之前項(xiàng)目中的復(fù)制過來)
#數(shù)據(jù)庫連接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/tlias
spring.datasource.username=root
spring.datasource.password=1234
#開啟mybatis的日志輸出
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#開啟數(shù)據(jù)庫表字段 到 實(shí)體類屬性的駝峰映射
mybatis.configuration.map-underscore-to-camel-case=true
- 實(shí)體類
/*部門類*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
private Integer id;
private String name;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
/*員工類*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
private Integer id;
private String username;
private String password;
private String name;
private Short gender;
private String image;
private Short job;
private LocalDate entrydate;
private Integer deptId;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
第4步:準(zhǔn)備對(duì)應(yīng)的Mapper、Service(接口、實(shí)現(xiàn)類)、Controller基礎(chǔ)結(jié)構(gòu)
數(shù)據(jù)訪問層:
- DeptMapper
package com.itheima.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DeptMapper {
}
- EmpMapper
package com.itheima.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface EmpMapper {
}
業(yè)務(wù)層:
- DeptService
package com.itheima.service;
//部門業(yè)務(wù)規(guī)則
public interface DeptService {
}
- DeptServiceImpl
package com.itheima.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
//部門業(yè)務(wù)實(shí)現(xiàn)類
@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
}
- EmpService
package com.itheima.service;
//員工業(yè)務(wù)規(guī)則
public interface EmpService {
}
- EmpServiceImpl
package com.itheima.service.impl;
import com.itheima.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
//員工業(yè)務(wù)實(shí)現(xiàn)類
@Slf4j
@Service
public class EmpServiceImpl implements EmpService {
}
控制層:
- DeptController
package com.itheima.controller;
import org.springframework.web.bind.annotation.RestController;
//部門管理控制器
@RestController
public class DeptController {
}
- EmpController
package com.itheima.controller;
import org.springframework.web.bind.annotation.RestController;
//員工管理控制器
@RestController
public class EmpController {
}
項(xiàng)目工程結(jié)構(gòu):
1.2 開發(fā)規(guī)范
了解完需求也完成了環(huán)境搭建了,我們下面開始學(xué)習(xí)開發(fā)的一些規(guī)范。
開發(fā)規(guī)范我們主要從以下幾方面介紹:
1、開發(fā)規(guī)范-REST
我們的案例是基于當(dāng)前最為主流的前后端分離模式進(jìn)行開發(fā)。
在前后端分離的開發(fā)模式中,前后端開發(fā)人員都需要根據(jù)提前定義好的接口文檔,來進(jìn)行前后端功能的開發(fā)。
后端開發(fā)人員:必須嚴(yán)格遵守提供的接口文檔進(jìn)行后端功能開發(fā)(保障開發(fā)的功能可以和前端對(duì)接)
而在前后端進(jìn)行交互的時(shí)候,我們需要基于當(dāng)前主流的REST風(fēng)格的API接口進(jìn)行交互。
什么是REST風(fēng)格呢?
- REST(Representational State Transfer),表述性狀態(tài)轉(zhuǎn)換,它是一種軟件架構(gòu)風(fēng)格。
傳統(tǒng)URL風(fēng)格如下:
http://localhost:8080/user/getById?id=1 GET:查詢id為1的用戶
http://localhost:8080/user/saveUser POST:新增用戶
http://localhost:8080/user/updateUser POST:修改用戶
http://localhost:8080/user/deleteUser?id=1 GET:刪除id為1的用戶
我們看到,原始的傳統(tǒng)URL呢,定義比較復(fù)雜,而且將資源的訪問行為對(duì)外暴露出來了。
基于REST風(fēng)格URL如下:
http://localhost:8080/users/1 GET:查詢id為1的用戶
http://localhost:8080/users POST:新增用戶
http://localhost:8080/users PUT:修改用戶
http://localhost:8080/users/1 DELETE:刪除id為1的用戶
其中總結(jié)起來,就一句話:通過URL定位要操作的資源,通過HTTP動(dòng)詞(請(qǐng)求方式)來描述具體的操作。
在REST風(fēng)格的URL中,通過四種請(qǐng)求方式,來操作數(shù)據(jù)的增刪改查。
- GET : 查詢
- POST :新增
- PUT :修改
- DELETE :刪除
我們看到如果是基于REST風(fēng)格,定義URL,URL將會(huì)更加簡(jiǎn)潔、更加規(guī)范、更加優(yōu)雅。
注意事項(xiàng):
- REST是風(fēng)格,是約定方式,約定不是規(guī)定,可以打破
- 描述模塊的功能通常使用復(fù)數(shù),也就是加s的格式來描述,表示此類資源,而非單個(gè)資源。如:users、emps、books…
2、開發(fā)規(guī)范-統(tǒng)一響應(yīng)結(jié)果
前后端工程在進(jìn)行交互時(shí),使用統(tǒng)一響應(yīng)結(jié)果 Result。
package com.itheima.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private Integer code;//響應(yīng)碼,1 代表成功; 0 代表失敗
private String msg; //響應(yīng)信息 描述字符串
private Object data; //返回的數(shù)據(jù)
//增刪改 成功響應(yīng)
public static Result success(){
return new Result(1,"success",null);
}
//查詢 成功響應(yīng)
public static Result success(Object data){
return new Result(1,"success",data);
}
//失敗響應(yīng)
public static Result error(String msg){
return new Result(0,msg,null);
}
}
3、開發(fā)流程
我們?cè)谶M(jìn)行功能開發(fā)時(shí),都是根據(jù)如下流程進(jìn)行:
-
查看頁面原型明確需求
- 根據(jù)頁面原型和需求,進(jìn)行表結(jié)構(gòu)設(shè)計(jì)、編寫接口文檔(已提供)
-
閱讀接口文檔
-
思路分析
-
功能接口開發(fā)
- 就是開發(fā)后臺(tái)的業(yè)務(wù)功能,一個(gè)業(yè)務(wù)功能,我們稱為一個(gè)接口
-
功能接口測(cè)試
- 功能開發(fā)完畢后,先通過Postman進(jìn)行功能接口測(cè)試,測(cè)試通過后,再和前端進(jìn)行聯(lián)調(diào)測(cè)試
-
前后端聯(lián)調(diào)測(cè)試
- 和前端開發(fā)人員開發(fā)好的前端工程一起測(cè)試
2. 部門管理
我們按照前面學(xué)習(xí)的開發(fā)流程,開始完成功能開發(fā)。首先按照之前分析的需求,完成部門管理
的功能開發(fā)。
開發(fā)的部門管理功能包含:
- 查詢部門
- 刪除部門
- 新增部門
- 更新部門(不講解,自己獨(dú)立完成)
2.1 查詢部門
2.1.1 原型和需求
查詢的部門的信息:部門ID、部門名稱、修改時(shí)間
通過頁面原型以及需求描述,我們可以看到,部門查詢,是不需要考慮分頁操作的。
2.1.2 接口文檔
部門列表查詢
-
基本信息
請(qǐng)求路徑:/depts 請(qǐng)求方式:GET 接口描述:該接口用于部門列表數(shù)據(jù)查詢
-
請(qǐng)求參數(shù)
無
-
響應(yīng)數(shù)據(jù)
參數(shù)格式:application/json
參數(shù)說明:
參數(shù)名 類型 是否必須 備注 code number 必須 響應(yīng)碼,1 代表成功,0 代表失敗 msg string 非必須 提示信息 data object[ ] 非必須 返回的數(shù)據(jù) |- id number 非必須 id |- name string 非必須 部門名稱 |- createTime string 非必須 創(chuàng)建時(shí)間 |- updateTime string 非必須 修改時(shí)間 響應(yīng)數(shù)據(jù)樣例:
{ "code": 1, "msg": "success", "data": [ { "id": 1, "name": "學(xué)工部", "createTime": "2022-09-01T23:06:29", "updateTime": "2022-09-01T23:06:29" }, { "id": 2, "name": "教研部", "createTime": "2022-09-01T23:06:29", "updateTime": "2022-09-01T23:06:29" } ] }
2.1.3 思路分析
2.1.4 功能開發(fā)
通過查看接口文檔:部門列表查詢
請(qǐng)求路徑:/depts
請(qǐng)求方式:GET
請(qǐng)求參數(shù):無
響應(yīng)數(shù)據(jù):json格式
DeptController
@Slf4j
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
//@RequestMapping(value = "/depts" , method = RequestMethod.GET)
@GetMapping("/depts")
public Result list(){
log.info("查詢所有部門數(shù)據(jù)");
List<Dept> deptList = deptService.list();
return Result.success(deptList);
}
}
@Slf4j注解源碼:
DeptService(業(yè)務(wù)接口)
public interface DeptService {
/**
* 查詢所有的部門數(shù)據(jù)
* @return 存儲(chǔ)Dept對(duì)象的集合
*/
List<Dept> list();
}
DeptServiceImpl(業(yè)務(wù)實(shí)現(xiàn)類)
@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public List<Dept> list() {
List<Dept> deptList = deptMapper.list();
return deptList;
}
}
DeptMapper
@Mapper
public interface DeptMapper {
//查詢所有部門數(shù)據(jù)
@Select("select id, name, create_time, update_time from dept")
List<Dept> list();
}
2.1.5 功能測(cè)試
功能開發(fā)完成后,我們就可以啟動(dòng)項(xiàng)目,然后打開postman,發(fā)起GET請(qǐng)求,訪問 :http://localhost:8080/depts
2.2 前后端聯(lián)調(diào)
完成了查詢部門的功能,我們也通過postman工具測(cè)試通過了,下面我們?cè)倩谇昂蠖朔蛛x的方式進(jìn)行接口聯(lián)調(diào)。具體操作如下:
1、將資料中提供的"前端環(huán)境"文件夾中的壓縮包,拷貝到一個(gè)沒有中文不帶空格的目錄下
2、拷貝到一個(gè)沒有中文不帶空格的目錄后,進(jìn)行解壓(解壓到當(dāng)前目錄)
3、啟動(dòng)nginx
4、打開瀏覽器,訪問:http://localhost:90
5、測(cè)試:部門管理 - 查詢部門列表
說明:只要按照接口文檔開發(fā)功能接口,就能保證前后端程序交互
- 后端:嚴(yán)格遵守接口文檔進(jìn)行功能接口開發(fā)
- 前端:嚴(yán)格遵守接口文檔訪問功能接口
2.3 刪除部門
查詢部門的功能我們搞定了,下面我們開始完成刪除部門
的功能開發(fā)。
2.3.1 需求
點(diǎn)擊部門列表后面操作欄的 “刪除” 按鈕,就可以刪除該部門信息。 此時(shí),前端只需要給服務(wù)端傳遞一個(gè)ID參數(shù)就可以了。 我們從接口文檔中也可以看得出來。
2.3.2 接口文檔
刪除部門
-
基本信息
請(qǐng)求路徑:/depts/{id} 請(qǐng)求方式:DELETE 接口描述:該接口用于根據(jù)ID刪除部門數(shù)據(jù)
-
請(qǐng)求參數(shù)
參數(shù)格式:路徑參數(shù)參數(shù)說明:
參數(shù)名 類型 是否必須 備注 id number 必須 部門ID 請(qǐng)求參數(shù)樣例:
/depts/1
-
響應(yīng)數(shù)據(jù)
參數(shù)格式:application/json參數(shù)說明:
參數(shù)名 類型 是否必須 備注 code number 必須 響應(yīng)碼,1 代表成功,0 代表失敗 msg string 非必須 提示信息 data object 非必須 返回的數(shù)據(jù) 響應(yīng)數(shù)據(jù)樣例:
{ "code":1, "msg":"success", "data":null }
2.3.3 思路分析
接口文檔規(guī)定:
- 前端請(qǐng)求路徑:/depts/{id}
- 前端請(qǐng)求方式:DELETE
問題1:怎么在controller中接收請(qǐng)求路徑中的路徑參數(shù)?
@PathVariable
問題2:如何限定請(qǐng)求方式是delete?
@DeleteMapping
2.3.4 功能開發(fā)
通過查看接口文檔:刪除部門
請(qǐng)求路徑:/depts/{id}
請(qǐng)求方式:DELETE
請(qǐng)求參數(shù):路徑參數(shù) {id}
響應(yīng)數(shù)據(jù):json格式
DeptController
@Slf4j
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@DeleteMapping("/depts/{id}")
public Result delete(@PathVariable Integer id) {
//日志記錄
log.info("根據(jù)id刪除部門");
//調(diào)用service層功能
deptService.delete(id);
//響應(yīng)
return Result.success();
}
//省略...
}
DeptService
public interface DeptService {
/**
* 根據(jù)id刪除部門
* @param id 部門id
*/
void delete(Integer id);
//省略...
}
DeptServiceImpl
@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public void delete(Integer id) {
//調(diào)用持久層刪除功能
deptMapper.deleteById(id);
}
//省略...
}
DeptMapper
@Mapper
public interface DeptMapper {
/**
* 根據(jù)id刪除部門信息
* @param id 部門id
*/
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
//省略...
}
2.3.5 功能測(cè)試
刪除功能開發(fā)完成后,重新啟動(dòng)項(xiàng)目,使用postman,發(fā)起DELETE請(qǐng)求:
2.3.6 前后端聯(lián)調(diào)
打開瀏覽器,測(cè)試后端功能接口:
2.4 新增部門
我們前面已完成了查詢部門
、刪除部門
兩個(gè)功能,也熟悉了開發(fā)的流程。下面我們繼續(xù)完成新增部門
功能。
2.4.1 需求
點(diǎn)擊 “新增部門” 按鈕,彈出新增部門對(duì)話框,輸入部門名稱,點(diǎn)擊 “保存” ,將部門信息保存到數(shù)據(jù)庫。
2.4.2 接口文檔
添加部門
-
基本信息
請(qǐng)求路徑:/depts 請(qǐng)求方式:POST 接口描述:該接口用于添加部門數(shù)據(jù)
-
請(qǐng)求參數(shù)
格式:application/json
參數(shù)說明:
參數(shù)名 類型 是否必須 備注 name string 必須 部門名稱 請(qǐng)求參數(shù)樣例:
{ "name": "教研部" }
-
響應(yīng)數(shù)據(jù)
參數(shù)格式:application/json
參數(shù)說明:
參數(shù)名 類型 是否必須 備注 code number 必須 響應(yīng)碼,1 代表成功,0 代表失敗 msg string 非必須 提示信息 data object 非必須 返回的數(shù)據(jù) 響應(yīng)數(shù)據(jù)樣例:
{ "code":1, "msg":"success", "data":null }
2.4.3 思路分析
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-rWAHAjIB-1681663580365)(assets/image-20221214115519648.png)]
接口文檔規(guī)定:
- 前端請(qǐng)求路徑:/depts
- 前端請(qǐng)求方式:POST
- 前端請(qǐng)求參數(shù) (Json格式):{ “name”: “教研部” }
問題1:如何限定請(qǐng)求方式是POST?
@PostMapping
問題2:怎么在controller中接收json格式的請(qǐng)求參數(shù)?
@RequestBody //把前端傳遞的json數(shù)據(jù)填充到實(shí)體類中
2.4.4 功能開發(fā)
通過查看接口文檔:新增部門
請(qǐng)求路徑:/depts
請(qǐng)求方式:POST
請(qǐng)求參數(shù):json格式
響應(yīng)數(shù)據(jù):json格式
DeptController
@Slf4j
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/depts")
public Result add(@RequestBody Dept dept){
//記錄日志
log.info("新增部門:{}",dept);
//調(diào)用service層添加功能
deptService.add(dept);
//響應(yīng)
return Result.success();
}
//省略...
}
DeptService
public interface DeptService {
/**
* 新增部門
* @param dept 部門對(duì)象
*/
void add(Dept dept);
//省略...
}
DeptServiceImpl
@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public void add(Dept dept) {
//補(bǔ)全部門數(shù)據(jù)
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
//調(diào)用持久層增加功能
deptMapper.inser(dept);
}
//省略...
}
DeptMapper
@Mapper
public interface DeptMapper {
@Insert("insert into dept (name, create_time, update_time) values (#{name},#{createTime},#{updateTime})")
void inser(Dept dept);
//省略...
}
2.4.5 功能測(cè)試
新增功能開發(fā)完成后,重新啟動(dòng)項(xiàng)目,使用postman,發(fā)起POST請(qǐng)求:
2.4.6 前后端聯(lián)調(diào)
打開瀏覽器,測(cè)試后端功能接口:
2.4.7 請(qǐng)求路徑
我們部門管理的查詢
、刪除
、新增
功能全部完成了,接下來我們要對(duì)controller層的代碼進(jìn)行優(yōu)化。
首先我們先來看下目前controller層代碼:
以上三個(gè)方法上的請(qǐng)求路徑,存在一個(gè)共同點(diǎn):都是以
/depts
作為開頭。(重復(fù)了)
在Spring當(dāng)中為了簡(jiǎn)化請(qǐng)求路徑的定義,可以把公共的請(qǐng)求路徑,直接抽取到類上,在類上加一個(gè)注解@RequestMapping,并指定請(qǐng)求路徑"/depts"。代碼參照如下:
優(yōu)化前后的對(duì)比:
注意事項(xiàng):一個(gè)完整的請(qǐng)求路徑,應(yīng)該是類上@RequestMapping的value屬性 + 方法上的 @RequestMapping的value屬性
3. 員工管理
完成了部門管理的功能開發(fā)之后,我們進(jìn)入到下一環(huán)節(jié)員工管理功能的開發(fā)。
基于以上原型,我們可以把員工管理功能分為:
- 分頁查詢(今天完成)
- 帶條件的分頁查詢(今天完成)
- 刪除員工(今天完成)
- 新增員工(后續(xù)完成)
- 修改員工(后續(xù)完成)
那下面我們就先從分頁查詢功能開始學(xué)習(xí)。
3.1 分頁查詢
3.1.1 基礎(chǔ)分頁
3.1.1.1 需求分析
我們之前做的查詢功能,是將數(shù)據(jù)庫中所有的數(shù)據(jù)查詢出來并展示到頁面上,試想如果數(shù)據(jù)庫中的數(shù)據(jù)有很多(假設(shè)有十幾萬條)的時(shí)候,將數(shù)據(jù)全部展示出來肯定不現(xiàn)實(shí),那如何解決這個(gè)問題呢?
使用分頁解決這個(gè)問題。每次只展示一頁的數(shù)據(jù),比如:一頁展示10條數(shù)據(jù),如果還想看其他的數(shù)據(jù),可以通過點(diǎn)擊頁碼進(jìn)行查詢。
要想從數(shù)據(jù)庫中進(jìn)行分頁查詢,我們要使用LIMIT
關(guān)鍵字,格式為:limit 開始索引 每頁顯示的條數(shù)
查詢第1頁數(shù)據(jù)的SQL語句是:
select * from emp limit 0,10;
查詢第2頁數(shù)據(jù)的SQL語句是:
select * from emp limit 10,10;
查詢第3頁的數(shù)據(jù)的SQL語句是:
select * from emp limit 20,10;
觀察以上SQL語句,發(fā)現(xiàn): 開始索引一直在改變 , 每頁顯示條數(shù)是固定的
開始索引的計(jì)算公式: 開始索引 = (當(dāng)前頁碼 - 1) * 每頁顯示條數(shù)
我們繼續(xù)基于頁面原型,繼續(xù)分析,得出以下結(jié)論:
- 前端在請(qǐng)求服務(wù)端時(shí),傳遞的參數(shù)
- 當(dāng)前頁碼 page
- 每頁顯示條數(shù) pageSize
- 后端需要響應(yīng)什么數(shù)據(jù)給前端
- 所查詢到的數(shù)據(jù)列表(存儲(chǔ)到List 集合中)
- 總記錄數(shù)
后臺(tái)給前端返回的數(shù)據(jù)包含:List集合(數(shù)據(jù)列表)、total(總記錄數(shù))
而這兩部分我們通常封裝到PageBean對(duì)象中,并將該對(duì)象轉(zhuǎn)換為json格式的數(shù)據(jù)響應(yīng)回給瀏覽器。
@Data @NoArgsConstructor @AllArgsConstructor public class PageBean { private Long total; //總記錄數(shù) private List rows; //當(dāng)前頁數(shù)據(jù)列表 }
3.1.1.2 接口文檔
員工列表查詢
-
基本信息
請(qǐng)求路徑:/emps 請(qǐng)求方式:GET 接口描述:該接口用于員工列表數(shù)據(jù)的條件分頁查詢
-
請(qǐng)求參數(shù)
參數(shù)格式:queryString
參數(shù)說明:
參數(shù)名稱 是否必須 示例 備注 name 否 張 姓名 gender 否 1 性別 , 1 男 , 2 女 begin 否 2010-01-01 范圍匹配的開始時(shí)間(入職日期) end 否 2020-01-01 范圍匹配的結(jié)束時(shí)間(入職日期) page 是 1 分頁查詢的頁碼,如果未指定,默認(rèn)為1 pageSize 是 10 分頁查詢的每頁記錄數(shù),如果未指定,默認(rèn)為10 請(qǐng)求數(shù)據(jù)樣例:
/emps?name=張&gender=1&begin=2007-09-01&end=2022-09-01&page=1&pageSize=10
-
響應(yīng)數(shù)據(jù)
參數(shù)格式:application/json
參數(shù)說明:
名稱 類型 是否必須 默認(rèn)值 備注 其他信息 code number 必須 響應(yīng)碼, 1 成功 , 0 失敗 msg string 非必須 提示信息 data object 必須 返回的數(shù)據(jù) |- total number 必須 總記錄數(shù) |- rows object [] 必須 數(shù)據(jù)列表 item 類型: object |- id number 非必須 id |- username string 非必須 用戶名 |- name string 非必須 姓名 |- password string 非必須 密碼 |- entrydate string 非必須 入職日期 |- gender number 非必須 性別 , 1 男 ; 2 女 |- image string 非必須 圖像 |- job number 非必須 職位, 說明: 1 班主任,2 講師, 3 學(xué)工主管, 4 教研主管, 5 咨詢師 |- deptId number 非必須 部門id |- createTime string 非必須 創(chuàng)建時(shí)間 |- updateTime string 非必須 更新時(shí)間 響應(yīng)數(shù)據(jù)樣例:
{ "code": 1, "msg": "success", "data": { "total": 2, "rows": [ { "id": 1, "username": "jinyong", "password": "123456", "name": "金庸", "gender": 1, "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg", "job": 2, "entrydate": "2015-01-01", "deptId": 2, "createTime": "2022-09-01T23:06:30", "updateTime": "2022-09-02T00:29:04" }, { "id": 2, "username": "zhangwuji", "password": "123456", "name": "張無忌", "gender": 1, "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg", "job": 2, "entrydate": "2015-01-01", "deptId": 2, "createTime": "2022-09-01T23:06:30", "updateTime": "2022-09-02T00:29:04" } ] } }
3.1.1.3 思路分析
分頁查詢需要的數(shù)據(jù),封裝在PageBean對(duì)象中:
3.1.1.4 功能開發(fā)
通過查看接口文檔:?jiǎn)T工列表查詢
請(qǐng)求路徑:/emps
請(qǐng)求方式:GET
請(qǐng)求參數(shù):跟隨在請(qǐng)求路徑后的參數(shù)字符串。 例:/emps?page=1&pageSize=10
響應(yīng)數(shù)據(jù):json格式
EmpController
import com.itheima.pojo.PageBean;
import com.itheima.pojo.Result;
import com.itheima.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
//條件分頁查詢
@GetMapping
public Result page(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize) {
//記錄日志
log.info("分頁查詢,參數(shù):{},{}", page, pageSize);
//調(diào)用業(yè)務(wù)層分頁查詢功能
PageBean pageBean = empService.page(page, pageSize);
//響應(yīng)
return Result.success(pageBean);
}
}
@RequestParam(defaultValue=“默認(rèn)值”) //設(shè)置請(qǐng)求參數(shù)默認(rèn)值
EmpService
public interface EmpService {
/**
* 條件分頁查詢
* @param page 頁碼
* @param pageSize 每頁展示記錄數(shù)
* @return
*/
PageBean page(Integer page, Integer pageSize);
}
EmpServiceImpl
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.PageBean;
import com.itheima.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
@Slf4j
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean page(Integer page, Integer pageSize) {
//1、獲取總記錄數(shù)
Long count = empMapper.count();
//2、獲取分頁查詢結(jié)果列表
Integer start = (page - 1) * pageSize; //計(jì)算起始索引 , 公式: (頁碼-1)*頁大小
List<Emp> empList = empMapper.list(start, pageSize);
//3、封裝PageBean對(duì)象
PageBean pageBean = new PageBean(count , empList);
return pageBean;
}
}
EmpMapper
@Mapper
public interface EmpMapper {
//獲取總記錄數(shù)
@Select("select count(*) from emp")
public Long count();
//獲取當(dāng)前頁的結(jié)果列表
@Select("select * from emp limit #{start}, #{pageSize}")
public List<Emp> list(Integer start, Integer pageSize);
}
3.1.1.5 功能測(cè)試
功能開發(fā)完成后,重新啟動(dòng)項(xiàng)目,使用postman,發(fā)起POST請(qǐng)求:
3.1.1.6 前后端聯(lián)調(diào)
打開瀏覽器,測(cè)試后端功能接口:
3.1.2 分頁插件
3.1.2.1 介紹
前面我們已經(jīng)完了基礎(chǔ)的分頁查詢,大家會(huì)發(fā)現(xiàn):分頁查詢功能編寫起來比較繁瑣。
在Mapper接口中定義兩個(gè)方法執(zhí)行兩條不同的SQL語句:
- 查詢總記錄數(shù)
- 指定頁碼的數(shù)據(jù)列表
在Service當(dāng)中,調(diào)用Mapper接口的兩個(gè)方法,分別獲?。嚎傆涗洈?shù)、查詢結(jié)果列表,然后在將獲取的數(shù)據(jù)結(jié)果封裝到PageBean對(duì)象中。
大家思考下:在未來開發(fā)其他項(xiàng)目,只要涉及到分頁查詢功能(例:訂單、用戶、支付、商品),都必須按照以上操作完成功能開發(fā)
結(jié)論:原始方式的分頁查詢,存在著"步驟固定"、"代碼頻繁"的問題
解決方案:可以使用一些現(xiàn)成的分頁插件完成。對(duì)于Mybatis來講現(xiàn)在最主流的就是PageHelper。
PageHelper是Mybatis的一款功能強(qiáng)大、方便易用的分頁插件,支持任何形式的單標(biāo)、多表的分頁查詢。
官網(wǎng):https://pagehelper.github.io/
在執(zhí)行empMapper.list()方法時(shí),就是執(zhí)行:select * from emp 語句,怎么能夠?qū)崿F(xiàn)分頁操作呢?
分頁插件幫我們完成了以下操作:
- 先獲取到要執(zhí)行的SQL語句:select * from emp
- 把SQL語句中的字段列表,變?yōu)椋篶ount(*)
- 執(zhí)行SQL語句:select count(*) from emp //獲取到總記錄數(shù)
- 再對(duì)要執(zhí)行的SQL語句:select * from emp 進(jìn)行改造,在末尾添加 limit ? , ?
- 執(zhí)行改造后的SQL語句:select * from emp limit ? , ?
3.1.2.2 代碼實(shí)現(xiàn)
當(dāng)使用了PageHelper分頁插件進(jìn)行分頁,就無需再M(fèi)apper中進(jìn)行手動(dòng)分頁了。 在Mapper中我們只需要進(jìn)行正常的列表查詢即可。在Service層中,調(diào)用Mapper的方法之前設(shè)置分頁參數(shù),在調(diào)用Mapper方法執(zhí)行查詢之后,解析分頁結(jié)果,并將結(jié)果封裝到PageBean對(duì)象中返回。
1、在pom.xml引入依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
2、EmpMapper
@Mapper
public interface EmpMapper {
//獲取當(dāng)前頁的結(jié)果列表
@Select("select * from emp")
public List<Emp> page(Integer start, Integer pageSize);
}
3、EmpServiceImpl
@Override
public PageBean page(Integer page, Integer pageSize) {
// 設(shè)置分頁參數(shù)
PageHelper.startPage(page, pageSize);
// 執(zhí)行分頁查詢
List<Emp> empList = empMapper.list(name,gender,begin,end);
// 獲取分頁結(jié)果
Page<Emp> p = (Page<Emp>) empList;
//封裝PageBean
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
return pageBean;
}
3.1.2.3 測(cè)試
功能開發(fā)完成后,我們重啟項(xiàng)目工程,打開postman,發(fā)起GET請(qǐng)求,訪問 :http://localhost:8080/emps?page=1&pageSize=5
后端程序SQL輸出:
3.2 分頁查詢(帶條件)
完了分頁查詢后,下面我們需要在分頁查詢的基礎(chǔ)上,添加條件。
3.2.1 需求
通過員工管理的頁面原型我們可以看到,員工列表頁面的查詢,不僅僅需要考慮分頁,還需要考慮查詢條件。 分頁查詢我們已經(jīng)實(shí)現(xiàn)了,接下來,我們需要考慮在分頁查詢的基礎(chǔ)上,再加上查詢條件。
我們看到頁面原型及需求中描述,搜索欄的搜索條件有三個(gè),分別是:
- 姓名:模糊匹配
- 性別:精確匹配
- 入職日期:范圍匹配
select *
from emp
where
name like concat('%','張','%') -- 條件1:根據(jù)姓名模糊匹配
and gender = 1 -- 條件2:根據(jù)性別精確匹配
and entrydate = between '2000-01-01' and '2010-01-01' -- 條件3:根據(jù)入職日期范圍匹配
order by update_time desc;
而且上述的三個(gè)條件,都是可以傳遞,也可以不傳遞的,也就是動(dòng)態(tài)的。 我們需要使用前面學(xué)習(xí)的Mybatis中的動(dòng)態(tài)SQL 。
3.2.2 思路分析
3.2.3 功能開發(fā)
通過查看接口文檔:?jiǎn)T工列表查詢
請(qǐng)求路徑:/emps
請(qǐng)求方式:GET
請(qǐng)求參數(shù):
參數(shù)名稱 是否必須 示例 備注 name 否 張 姓名 gender 否 1 性別 , 1 男 , 2 女 begin 否 2010-01-01 范圍匹配的開始時(shí)間(入職日期) end 否 2020-01-01 范圍匹配的結(jié)束時(shí)間(入職日期) page 是 1 分頁查詢的頁碼,如果未指定,默認(rèn)為1 pageSize 是 10 分頁查詢的每頁記錄數(shù),如果未指定,默認(rèn)為10
在原有分頁查詢的代碼基礎(chǔ)上進(jìn)行改造:
EmpController
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
//條件分頁查詢
@GetMapping
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("分頁查詢,參數(shù):{},{},{},{},{},{}", page, pageSize,name, gender, begin, end);
//調(diào)用業(yè)務(wù)層分頁查詢功能
PageBean pageBean = empService.page(page, pageSize, name, gender, begin, end);
//響應(yīng)
return Result.success(pageBean);
}
}
EmpService
public interface EmpService {
/**
* 條件分頁查詢
* @param page 頁碼
* @param pageSize 每頁展示記錄數(shù)
* @param name 姓名
* @param gender 性別
* @param begin 開始時(shí)間
* @param end 結(jié)束時(shí)間
* @return
*/
PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end);
}
EmpServiceImpl
@Slf4j
@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) {
//設(shè)置分頁參數(shù)
PageHelper.startPage(page, pageSize);
//執(zhí)行條件分頁查詢
List<Emp> empList = empMapper.list(name, gender, begin, end);
//獲取查詢結(jié)果
Page<Emp> p = (Page<Emp>) empList;
//封裝PageBean
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
return pageBean;
}
}
EmpMapper
@Mapper
public interface EmpMapper {
//獲取當(dāng)前頁的結(jié)果列表
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
}
EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!-- 條件分頁查詢 -->
<select id="list" resultType="com.itheima.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
</select>
</mapper>
3.2.4 功能測(cè)試
功能開發(fā)完成后,重啟項(xiàng)目工程,打開postman,發(fā)起GET請(qǐng)求:
控制臺(tái)SQL語句:
3.2.5 前后端聯(lián)調(diào)
打開瀏覽器,測(cè)試后端功能接口:
3.3 刪除員工
查詢員完成之后,我們繼續(xù)開發(fā)新的功能:刪除員工。
3.3.1 需求
當(dāng)我們勾選列表前面的復(fù)選框,然后點(diǎn)擊 “批量刪除” 按鈕,就可以將這一批次的員工信息刪除掉了。也可以只勾選一個(gè)復(fù)選框,僅刪除一個(gè)員工信息。
問題:我們需要開發(fā)兩個(gè)功能接口嗎?一個(gè)刪除單個(gè)員工,一個(gè)刪除多個(gè)員工
答案:不需要。 只需要開發(fā)一個(gè)功能接口即可(刪除多個(gè)員工包含只刪除一個(gè)員工)
3.3.2 接口文檔
刪除員工
-
基本信息
請(qǐng)求路徑:/emps/{ids} 請(qǐng)求方式:DELETE 接口描述:該接口用于批量刪除員工的數(shù)據(jù)信息
-
請(qǐng)求參數(shù)
參數(shù)格式:路徑參數(shù)
參數(shù)說明:
參數(shù)名 類型 示例 是否必須 備注 ids 數(shù)組 array 1,2,3 必須 員工的id數(shù)組 請(qǐng)求參數(shù)樣例:
/emps/1,2,3
-
響應(yīng)數(shù)據(jù)
參數(shù)格式:application/json
參數(shù)說明:
參數(shù)名 類型 是否必須 備注 code number 必須 響應(yīng)碼,1 代表成功,0 代表失敗 msg string 非必須 提示信息 data object 非必須 返回的數(shù)據(jù) 響應(yīng)數(shù)據(jù)樣例:
{ "code":1, "msg":"success", "data":null }
3.3.3 思路分析
接口文檔規(guī)定:
- 前端請(qǐng)求路徑:/emps/{ids}
- 前端請(qǐng)求方式:DELETE
問題1:怎么在controller中接收請(qǐng)求路徑中的路徑參數(shù)?
@PathVariable
問題2:如何限定請(qǐng)求方式是delete?
@DeleteMapping
問題3:在Mapper接口中,執(zhí)行delete操作的SQL語句時(shí),條件中的id值是不確定的是動(dòng)態(tài)的,怎么實(shí)現(xiàn)呢?
Mybatis中的動(dòng)態(tài)SQL:foreach
3.3.4 功能開發(fā)
通過查看接口文檔:刪除員工
請(qǐng)求路徑:/emps/{ids}
請(qǐng)求方式:DELETE
請(qǐng)求參數(shù):路徑參數(shù) {ids}
響應(yīng)數(shù)據(jù):json格式
EmpController
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
//批量刪除
@DeleteMapping("/{ids}")
public Result delete(@PathVariable List<Integer> ids){
empService.delete(ids);
return Result.success();
}
//條件分頁查詢
@GetMapping
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("分頁查詢,參數(shù):{},{},{},{},{},{}", page, pageSize,name, gender, begin, end);
//調(diào)用業(yè)務(wù)層分頁查詢功能
PageBean pageBean = empService.page(page, pageSize, name, gender, begin, end);
//響應(yīng)
return Result.success(pageBean);
}
}
EmpService
public interface EmpService {
/**
* 批量刪除操作
* @param ids id集合
*/
void delete(List<Integer> ids);
//省略...
}
EmpServiceImpl
@Slf4j
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public void delete(List<Integer> ids) {
empMapper.delete(ids);
}
//省略...
}
EmpMapper
@Mapper
public interface EmpMapper {
//批量刪除
void delete(List<Integer> ids);
//省略...
}
EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--批量刪除員工-->
<select id="delete">
delete from emp where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
<!-- 省略... -->
</mapper>
3.3.5 功能測(cè)試
功能開發(fā)完成后,重啟項(xiàng)目工程,打開postman,發(fā)起DELETE請(qǐng)求:
控制臺(tái)SQL語句:
3.3.6 前后端聯(lián)調(diào)
打開瀏覽器,測(cè)試后端功能接口:
文章來源:http://www.zghlxwxcb.cn/news/detail-439247.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-439247.html
到了這里,關(guān)于基于springboot的前后端分離的案列(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!