欢迎光临
我们一直在努力

实战:SpringBoot+MyBatis整合开发案例【个人心得】

前面介绍了很多的技术栈,今天就尝试的把这些技术栈结合起来,尝试着去完成一个小案例。

准备工作

项目的开发过程中,肯定要有准备工作,比如需求文档的拟定,接口文档的拟定,这些都是在项目开展之前要完成的事情。

需求文档的拟定:一般是产品经理根据自身产品需求来拟定的文档,开发人员需严格遵循开发文档进行开发,在开发过程中需与产品经理沟通,确定产品开发过程是符合预期的

接口文档的拟定:是建立在需求文档的基础上进行开发写作的,其主要是由后端人员来拟定,主要是用于前后端之间进行交互的。

项目环境的搭建:

介绍一下工作流程:

  • 前端发送请求到达后端,后端根据接收到的请求进行对应的业务处理
  • 在后端进行业务处理的过程中,需要与MySQL服务器进行数据之间的交流
  • 当业务需求处理完成后,需要向前端发起一个响应,将处理好的结果进行返回
  • 项目结构:

    根据上述流程,需要准备的环境:

  • MySQL服务器当中的数据表
  • spring boot工程,需要引入 web,mybatis,MySQL驱动,lombok等依赖
  • 需要在property中配置mybatis的信息,准备好对应的实体类信息
  • 准备好对应的mapper,service接口,controller信息【基于三层架构进行开发】
  • 【该案例是结合后端开发的三层架构进行开发的】

    那什么是开发过程中的三层架构呢,具体可以参考这篇文章:

    https://blog.csdn.net/2403_87933448/article/details/156834576?fromshare=blogdetail&sharetype=blogdetail&sharerId=156834576&sharerefer=PC&sharesource=2403_87933448&sharefrom=from_link

    在开发过程中,一般是采用rest风格进行开发

    在一般的开发过程中,通常是根据程序员个人的偏好来进行了各种url的访问方式,但是这种方式不利于后续服务器的维护和团队的沟通交流

    因此一般是采用rest风格的url,进行前后端之间的交流,同时也规范了get,post,put,delete的适用范围以及定下了相关的规范!

    同时也需要有统一的响应结果

    上面的准备工作完成之后,那么我们就要准备接下来的开发功能了

    部门管理

    查询部门

    系统工作流程:
  • 前端发起请求到达controller层
  • controller调用service去查询相关的部门有哪些
  • service接着调用mapper接口
  • 将得到的信息返回到service层
  • service进行业务的处理之后,将信息传递给controller层
  • controller将数据处理的结果按统一的格式进行返回!
  • 备注:

    1.日志的输出方式

    在开发的过程中,我们一般不使用system.out.println来输出日志

    一般是采用下面固定格式来进行日志的输出展示 log.info()

    或者直接调用注解 @Slf4j即可

    2.responsebody

    因为我们在controller层中调用了@RestController注解,在注解中包括了responsebody的注解

    responsebody这个注解的主要作用是将返回的值以JSON格式进行输出。

    3.限制数据的请求方式,比如我限制了数据的请求方式为get

    因此不能使用post进行请求

    代码书写的过程:

    严格按照上述系统的工作流程来进行书写

  • 先写好controller内部的接口,调用的方式,返回值的方式等
  • 然后在controller里面去写对应的service,调用service的接口
  • package com.itheima.controller;

    import com.itheima.pojo.Dept;
    import com.itheima.pojo.Result;
    import com.itheima.service.DeptService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;

    import java.util.List;

    /**
    * 部门管理Controller
    */
    @Slf4j
    @RestController

    public class DeptController {

    @Autowired
    private DeptService deptService;

    @RequestMapping(value = "/depts",method = RequestMethod.GET)
    public Result list(){
    log.info("查询全部部门的数据");

    List<Dept> deptList=deptService.list();

    return Result.success(deptList);
    }
    }

  • 接着在service接口里面去调用mapper
  • @Service
    public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<Dept> list() {
    return deptMapper.list();
    }
    }

  • 然后在mapper里面书写对应的sql语句即可
  • @Mapper
    public interface DeptMapper {
    /*
    * 查询全部的部门数据
    * */
    @Select("select * from dept")
    List<Dept> list();
    }
  • 最后程序将处理好的数据返回给前端,进行逐级响应
  • 前后端联调

    根据准备好的前端程序,跳转到指定的页面进行相对应的调试工作

    可以打开开发工具查看 前端页面发起的请求,以及后端给前端对应的响应。

    删除部门

    根据id去删除部门

    删除部门的思路:

    其本质上是和前面的查询部门是差不多的,工作的基本流程是建立在三层架构上的

  • 还是前端用户发送一个请求,到达controller层,数据被接收
  • 然后controller层,需要引入一个新的注解 pathvariable ,用于接收对应的参数id,然后是controller层调用service层的接口
  • @DeleteMapping(value = "/depts/{id}")
    public Result delete(@PathVariable Integer id){
    log.info("删除了的部门的id为:{}",id);
    deptService.delete(id);
    return Result.success();
  • service层接着去调用mapper层进行相关的操作
  • @Override
    public void delete(Integer id) {
    deptMapper.deleteById(id);
    }
  • mapper层执行对应的sql语句
  • @Delete("delete from dept where id=#{id}")
    void deleteById(Integer id);
  • 将处理好的数据逐级返回即可,最终在前端页面显示对应的数据
  • 注意不要忘记了传递过程中的id
  • 新增部门

    工作流程及其代码:

  • 前端用户根据自身的需求发送一个请求到达服务器,服务器的controller层接收到对应的数据
  • 然后controller调用service层的接口执行对应的代码
  • @PostMapping("/depts")
    public Result add(@RequestBody Dept dept){
    log.info("新增部门:{}",dept);
    deptService.add(dept);
    return Result.success();
    }
  • 接着service层里面接着去调用mapper的接口
  • @Override
    public void add(Dept dept) {
    dept.setCreateTime(LocalDateTime.now());
    dept.setUpdateTime(LocalDateTime.now());
    deptMapper.add(dept);
    }
  • mapper被调用之后接着去执行里面的sql语句
  • @Insert("insert into dept(name, create_time, update_time) VALUES (#{name},#{createTime},#{updateTime})")
    void add(Dept dept);
  • 将处理好的数据逐级返回,最后进行响应即可
  • 备注:【增加】

  • 新增部门的时候,需要用到 @requestbody的注解
  • 接着是注意在service层补充对应的基础属性,比如updatetime,createtime这些属性
  • 以及是最后sql语句的正确编写insert语句
  • 可以考虑将对应的格式进行进一步的简化操作:

    员工管理:

    分页查询:
    一般查询【无条件查询】:
    首先是对 分页查询语句 的回顾
  • 用到关键字select和limit。limit关键字第一个参数传递起始参数【索引是从0开始的】,然后是每页查询/展示的条数
  • 起始索引=(页码-1)*每页展示的记录数
  • 根据业务需求进行分析

    发现我们需要返回两条信息给前端交互页面,但是我们一般都是一次返回一条信息,因此在这里可以考虑使用一个类对需要响应的数据进行接收,然后再将这个类返回给前端服务器

    备注:

    属性名的命名需要与接口文档保持一致。

    如果传入的参数是空且业务需求中有要求传递一个默认值,则考虑引入@requestparam注解,有几个参数,就需要引入几个这样的注解

    工作流程+代码:
  • 首先还是用户发送一个查表的请求到达后端的controller层
  • controller层需要根据发送的请求以及开发文档的说明,提取对应的参数。关键还是看开发文档的需求,决定是否需要引入requestparam来设置对应的默认值
  • @Slf4j
    @RestController
    public class EmpController {

    @Autowired
    private EmpService empService;

    @GetMapping("/emps")
    public Result page(@RequestParam(defaultValue = "1") Integer page,
    @RequestParam(defaultValue = "10") Integer pageSize){
    PageBean pageBean=empService.page(page,pageSize);
    log.info("页码:{},{}",page,pageSize);
    return Result.success(pageBean);
    }
    }

  • 接着肯定是调用service层的接口,并将参数传递过去。
  • 然后是service层,根据业务开发的需求,首先是需要统计有多少条记录符合要求的,调用mapper接口去实现对应的功能,然后是计算出起始索引和每页展示的条数传递给mapper接口中的第二个方法去获取对应的数据,存放在list集合中,最后是new一个类,将上面获取到的信息进行封装处理,进行返回给controller层。
  • @Service
    public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Override
    public PageBean page(Integer page, Integer pageSize) {
    Integer count =empMapper.count();

    Integer start=(page-1)*pageSize;
    List<Emp> empList=empMapper.page(start,pageSize);

    PageBean pageBean=new PageBean(count,empList);
    return pageBean;
    }
    }

  • 接着是写service层调用到的方法,需要编写对应的SQL语句去实现对应的功能。注意如果是有很多条数据,可以考虑使用集合将数据进行打包再将其进行返回操作

  • @Mapper
    public interface EmpMapper {
    @Select("select count(*) from emp")
    Integer count();

    @Select("select * from emp limit #{start},#{pageSize}")
    public List<Emp> page(Integer start,Integer pageSize);
    }

  • 最后肯定是将数据打包返回到前端界面进行展示了

  • pagehelper插件

    条件查询:

    需要用到动态sql

    思路

    用到的代码

    controller

    @Slf4j
    @RestController
    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={}", page, pageSize);
    log.info("接收的筛选参数:name={}, gender={}, begin={}, end={}", name, gender, begin, end);

    PageBean pageBean=empService.page(page,pageSize,name,gender,begin,end);
    log.info("分页查询结果已封装,总记录数={}", pageBean.getTotal());
    return Result.success(pageBean);
    }
    }

    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) {
    Integer count =empMapper.count(name, gender, begin, end);

    Integer start=(page-1)*pageSize;
    List<Emp> empList=empMapper.page(start,pageSize,name,gender,begin,end);

    PageBean pageBean=new PageBean(count,empList);
    return pageBean;
    }

    }

    mapper

    @Mapper
    public interface EmpMapper {

    // 统计方法:所有参数添加@Param注解,与XML中的参数名对应
    Integer count(
    @Param("name") String name,
    @Param("gender") Short gender,
    @Param("begin") LocalDate begin,
    @Param("end") LocalDate end
    );

    // 分页方法:所有参数添加@Param注解,与XML中的参数名对应
    List<Emp> page(
    @Param("start") Integer start,
    @Param("pageSize") Integer pageSize,
    @Param("name") String name,
    @Param("gender") Short gender,
    @Param("begin") LocalDate begin,
    @Param("end") LocalDate end
    );

    }

    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">

    <!– 1. 条件查询:统计符合条件的总记录数(对应mapper的count方法) –>
    <select id="count" resultType="java.lang.Integer">
    select count(*)
    from emp
    <where>
    <!– 完善:非null 且 非空字符串 –>
    <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>
    </select>

    <!– 2. 条件查询:分页查询员工数据(对应mapper的page方法) –>
    <select id="page" resultType="com.itheima.pojo.Emp">
    select *
    from emp
    <where>
    <!– 完善:非null 且 非空字符串 –>
    <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>

    赞(0)
    未经允许不得转载:171主机测评 » 实战:SpringBoot+MyBatis整合开发案例【个人心得】
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址