P135 案例-准备工作
依据案例,学习根据接口文档开发接口的能力。
完成部门管理和员工管理两部分。可以分析这两部分,一个部门可以有多个员工,一个员工归属一个部门。
准备数据库表,创建一个springboot工程,引入web开发起步依赖、mybatis相关依赖(mybatis起步依赖,mysql驱动)、简化实体类定义引入lombok,如下图
配置mybatis,准备对应实体类,准备三层架构的基础代码,之前的Dao就是mybatis下的数据访问层,mapper层。
采用面向接口的方式编程。
了解开发规范:基于当前主流的前后端分离进行开发,服务端运行在tomcat服务器上。开发规范定义在接口文档当中,前后端交互的时候是基于restful风格进行交互的。
开发规范Restful:Representational State Transfer,表述性状态转换,是一种软件架构风格。
描述网络资源有两种方式,
- 传统风格,自己定义的url,请求方式也是不统一,例如user/getByid?id=1, user/saveUser,等等
-
restful风格,通过url定位资源,例如user/1, user/users,等等,这些url只知道是对user进行操作,具体是什么请求要通过HTTP动词描述操作,即请求方式的对应操作
-
GET查询操作
-
POST新增操作
-
PUT修改操作
-
DELETE删除操作
-
注意rest是风格,约定方式,可以打破;描述模块的功能通常使用复数,也就加s的格式描述,
基础环境已经准备好了,开发流程是怎么样的:
-
查看页面原型,明确需求
-
阅读接口文档
-
思路分析
-
接口开发
-
接口测试
-
前后端联调
P136 案例-部门管理-查询
只是仅仅进行查询数据并返回即可。理解整个流程处理请求调用mapper接口,执行查询后返回结果。
如果使用日志,可以如下:
private static Logger log = LoggerFactory.getLogger(DeptController.class);
log.info()
上述步骤可以简化为使用lombok中的注解,@Slf4j,然后直接使用log记录日志
使用@Requestmapping()需要指定Url和请求方式method=。
除此之外还有衍生注解更为方便:
-
GetMapping
-
PostMapping
-
PutMapping
在controller中是使用了service的方法,然后可以直接在这里快捷生成方法,然后再在serviceimpl中实现接口类,然后接口类中实现mapper方法,快速生成mapper方法,再到xml中定义sql语句。
P137 案例-部门管理-前后端联调
前端工程一般部署在nginx服务器当中的,将案例中部署好的nginx解压,然后双击nginx.exe即可运行,
P138 案例-部门管理-删除
回顾接收路径参数的方式,使用注解@Pathvariable,
/**
* 删除部门信息
* @param id
* @return
*/
@DeleteMapping("/depts/{id}")
public Result delete(@PathVariable Integer id){
log.info("删除部门一条记录:"+id);
// 执行删除操作
deptService.delete();
return Result.success();
}
联调成功。
P139 案例-部门管理-新增部门
注意接口文档中的请求参数为application/json的格式,不是路径参数的格式。
回顾服务端接收json形式的方法,加上注解@RequestBody,使用实体类接收。
@PostMapping("/depts")
public Result insert(@RequestBody Dept dept){
log.info("新增部门:{}", dept);
deptService.insert(dept);
return Result.success();
}
分析,以上增删改查的路径都有公共的部分,可以抽取出公共的路径,放在类的前面使用Requestmapping。
P140 案例-员工管理-分页查询-分析
先不加条件,先实现查询出数据进行分页展示,
回顾:mysql分页查询基本语法,第一页索引从0开始,
select * from limit 起始索引, 查询返回的记录数
起始索引的计算公式,(页码 - 1)*每页展示记录数
获取总记录数的sql, select count(*) from emp
。
前端传递:page,pageSize
后端响应:list, total。两项数据建议使用map集合或者实体类封装进行返回,建议使用实体类封装。
P141 案例-员工管理-分页查询-实现
对于前端传递的page和pageSize,如果没有传递则后端要设置默认值,可以使用注解ReqeustParam进行默认值的设置,
分页查询的实现:
@Mapper
public interface EmpMapper {
/**
* 获取总记录数
*/
public Long count();
/**
* 按分页查询返回结果
*/
public List<Emp> page(Integer start, Integer pageSize);
}
业务逻辑处理实现:将两个结果封装
@Override
public PageBean page(Integer page, Integer pageSize) {
// 获取总记录数
Long count = empMapper.count();
// 获取分页查询列表
List<Emp> page1 = empMapper.page((page - 1) * pageSize, pageSize);
// 封装pageBean
PageBean pageBean = new PageBean();
pageBean.setTotal(count);
pageBean.setRows(page1);
return pageBean;
}
P142 案例-员工管理-分页插件PageHelper
分析上述的原始实现的分页查询,这类操作步骤固定、代码繁琐。较为流行的是PageHelper插件,简化这类操作。
我们只需要查询即可,查询第多少页,每页多少,则通过PageHelper进行设置,
将查询结果转为Page类型。
先引入依赖:注意版本1.4.6才能将后面查询到的list数据转成page数据
<!-- pagehelper依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
在Mapper接口中执行正常的查询即可,
然后将原始的逻辑处理进行修改,
@Override
public PageBean page(Integer page, Integer pageSize) {
// 设置分页参数
PageHelper.startPage(page, pageSize);
// 执行正常的查询
List<Emp> empList = empMapper.list();
// 变为Page类型
Page<Emp> p = (Page<Emp>) empList;
//封装结果
PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
return pageBean;
}
P143 案例-员工管理-分页条件查询
条件查询即sql语句中增加where条件,
select * from emp where name like concat('%', ${name},'%') and gender = 1 and entrydate between #{start} and #{end} order by update_time desc;
在上述分页查询的基础上增加查询条件,sql使用动态sql实现,
P144 案例-员工管理-删除
分单个删除和批量删除。
动态sql语句,使用到了foreach标签。
P145 案例-员工管理-新增员工
例如:
@PostMapping
public Result add(@RequestBody Emp emp){
log.info("新增员工: {}", emp);
empService.add(emp);
return Result.success();
}
小结:
如果是路径中参数,在函数参数定义中加上注解@Pathvariable
如果是json请求数据,在函数参数中加上注解@RequestBody