目录
一、建立项目的基本操作步骤
二、前期搭建环境
1、创建springboot工程
2、引入对应依赖
3、对建立好的框架进行调试
(1)pom.xml没有显示蓝色怎么解决?
(2) 启动类为橙红色java文件怎么办?
4、配置application.properties文件
5、准备Mapper、Service、Controller基础结构
(1)controller层 - java类
(2)mapper层 - 接口
(3)service层 - 接口+实现类
① 实现类
② 接口
(4)pojo实体类
6、引入统一接口风格的响应类Result
三、部门管理功能开发
1、部门列表查询
(1)Controller类
(2)Service类
(3)Mapper类
(4)测试
2、前后端联调
3、删除部门
(1)Controller类
(2)Service类
(3)Mapper类
(4)测试
4、添加部门
(1)Controller类
(2)Service类
(3)Mapper类
(4)测试
5、优化
6、根据id查询部门
(1)Controller类
(2)Service类
(3)Mapper类
(4)测试
7、修改
(1)Controller类
(2)Service类
(3)Mapper类
(4)测试
8、部门管理代码综合展示
(1)DeptController类
(2)DeptService 接口
(3)DeptServiceImpl 实现类
(4)DeptMapper类
四、员工管理功能开发
1、分页查询 - 原始代码
(1)复习SQL分页查询语法
(2)需求分析
(3)定义PageBean类
(4)员工列表查询
(1)Controller类
① 设置请求参数默认值 @RequestParam(defaultValue="1")
(2)Service类
(3)Mapper类
(4)测试
2、分页插件 PageHelper
(1)引入pagehelper依赖
(2)Controller类
(3)Service类
(4)Mapper类
3、条件分页查询
(1)动态sql - 配置xml文件
① 在resource文件下建包
② 配置EmpMapper.xml文件
③ namespace属性名与mapper接口名全限定名一致
④ sql语句的id与mapper接口中方法名一致
⑤ sql语句中 resultType 返回结果类型为封装类的全限定名
⑥ 输入SQL语句并将参数改为动态
⑦ 对sql代码改为 动态SQL
(3)Service类
(4)Mapper类
4、删除员工
(1)配置动态sql xml文件
(2)Controller类
(3)Service类
(4)Mapper类
一、建立项目的基本操作步骤
- 准备数据库表(dept表,emp表)
- 创建springboot工程,引入对应的起步依赖(web,mybatis,mysql驱动,lombok)
- 配置文件application.properties中引入mybatis配置信息,准备对应实体类
- 准备对应的Mapper,Service(接口,实现类),Controller基础结构
二、前期搭建环境
1、创建springboot工程
2、引入对应依赖
3、对建立好的框架进行调试
(1)pom.xml没有显示蓝色怎么解决?
(2) 启动类为橙红色java文件怎么办?
点击File,选择Project Structure
将想要设置的工程中的java包选中,然后点击Sources,即可点亮
4、配置application.properties文件
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
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
#开启mybatis的驼峰命名自动映射开关 a_column ------> aCloumn
mybatis.configuration.map-underscore-to-camel-case=true
5、准备Mapper、Service、Controller基础结构
(1)controller层 - java类
package com.itroye.controller;
import org.springframework.web.bind.annotation.RestController;
//部门管理controller
@RestController
public class DeptController {
}
(2)mapper层 - 接口
package com.itroye.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DeptMapper {
}
(3)service层 - 接口+实现类
① 实现类
package com.itroye.service.impl.impl;
import com.itroye.service.impl.DeptService;
import org.springframework.stereotype.Service;
@Service
public class DeptServiceImpl implements DeptService {
}
② 接口
package com.itroye.service.impl;
public interface DeptService {
}
(4)pojo实体类
package com.itroye.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
// 员工实体类
@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;
}
package com.itroye.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
// 部门实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
private Integer id;
private String name;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
6、引入统一接口风格的响应类Result
package com.itroye.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);
}
}
三、部门管理功能开发
具体流程:
- 前端发送请求后,会请求到controller这个方法,controller方法首先会调用service获取数据
- 在service方法中调用了mapper接口中的方法来查询数据
- mapper接口会往数据库里发送sql查询语句,并把查询的信息封装到List集合中,并将该集合数据返回给service
- service又返回给controller,controller拿到数据后返回给前端
1、部门列表查询
接口信息:
- 请求方式:GET —— @GetMapping
- 请求路径:("/depts")
请求参数:无
响应数据:dept类
(1)Controller类
//部门管理controller
@Slf4j
@RestController
public class DeptController {
@Autowired
private DeptService deptService; //调用service接口
@GetMapping("/depts")
public Result list()
{
log.info("查询全部部门数据");
//调用service查询部门数据
List<Dept> deptList = deptService.list();
return Result.success(deptList);
}
}
在启动类点击运行,然后在下方提示框显示端口号8080
(2)Service类
点击controller类中list方法,按alt+enter自动跳转到service接口,并生成list方法
public interface DeptService {
//查询全部部门数据
List<Dept> list();
}
点击左侧小绿圈,跳转到service实现类
选中类名,按alt+enter自动生成接口的实现方法
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper; //调用mapper接口
@Override
public List<Dept> list() {
return deptMapper.list();
}
}
(3)Mapper类
最后mapper通过@select注解中的sql语句,在数据库中查询数据并封装到list类
@Mapper
public interface DeptMapper {
//查询全部部门数据
@Select("select * from dept")
List<Dept> list();
}
(4)测试
打开postman进行测试,收到从数据库中查询到的数据
localhost:8080/depts
2、前后端联调
Day10-03. 案例-部门管理-前后端联调_哔哩哔哩_bilibili
3、删除部门
接口信息:
- 请求方式:DELETE —— @DeleteMapping
- 请求路径:("/depts/{id}")
请求参数:路径参数 @PathVariable
响应数据:直接Result.success()
(1)Controller类
//删除
@DeleteMapping("/depts/{id}")
public Result delete(@PathVariable Integer id)
{
log.info("根据id删除部门:{}",id);
//调用service删除部门
deptService.delete(id);
return Result.success();
}
(2)Service类
public interface DeptService {
//删除部门
void delete(Integer id);
}
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper; //调用mapper接口
@Override
public void delete(Integer id) {
deptMapper.deleteById();
}
}
(3)Mapper类
@Mapper
public interface DeptMapper {
//删除数据
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
}
(4)测试
4、添加部门
接口信息:
- 请求方式:POST —— @PostMapping
- 请求路径:("/depts")
请求参数:json格式数据,需要封装到实体类
json格式的参数需要加上注解 @RequestBody
【javaweb】学习日记Day5 - 请求响应 分层解耦 IOC DI 三层架构_Roye_ack的博客-CSDN博客
响应数据: 直接Result.success()
(1)Controller类
//新增
@PostMapping("/depts")
public Result add(@RequestBody Dept dept)
{
log.info("新增部门:{}",dept);
//调用service新增部门
deptService.add(dept);
return Result.success();
}
(2)Service类
public interface DeptService {
//新增部门
void add(Dept dept);
}
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper; //调用mapper接口
@Override
public void add(Dept dept) {
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
deptMapper.add(dept);
}
}
(3)Mapper类
@Mapper
public interface DeptMapper {
//新增数据
@Insert("insert into dept(name,create_time,update_time) values(#{name},#{createTime},#{updateTime})")
void add(Dept dept);
}
(4)测试
5、优化
- 请求路径"/depts"重复,可以放在类上
- 一个完整的请求路径,应该是类上的@RequestMapping 的value属性+方法上的@RequestMapping的value属
6、根据id查询部门
接口信息
- 请求方式:GET —— @GetMapping
- 请求路径:("/depts/{id}")
请求参数:
响应数据:dept类
(1)Controller类
//根据id查询数据
@GetMapping("/{id}")
public Result getByID(@PathVariable Integer id)
{
log.info("获取部门id:{}",id);
Dept dept = deptService.getByID(id);
return Result.success(dept);
}
(2)Service类
//根据id查询部门
Dept getByID(Integer id);
@Override
public Dept getByID(Integer id) {
Dept dept = deptMapper.getByID(id);
return dept;
}
(3)Mapper类
//根据id获取部门
@Select("select * from dept where id = #{id}")
Dept getByID(Integer id);
(4)测试
7、修改
接口信息
- 请求方式:PUT —— @PutMapping
- 请求路径:("/depts")
响应数据:直接Result.success()
(1)Controller类
//修改
@PutMapping
public Result modify(@RequestBody Dept dept)
{
log.info("修改数据:{}",dept.getId());
//调用service修改数据
deptService.modify(dept);
return Result.success();
}
(2)Service类
public interface DeptService {
//修改部门
void modify(Dept dept);
}
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper; //调用mapper接口
@Override
public void modify(Dept dept) {
dept.setUpdateTime(LocalDateTime.now());
deptMapper.modify(dept);
}
}
(3)Mapper类
@Mapper
public interface DeptMapper {
//修改数据
@Update("update dept set name = #{name},update_time = #{updateTime} where id = #{id}")
void modify(Dept dept);
}
(4)测试
8、部门管理代码综合展示
(1)DeptController类
//部门管理controller
@Slf4j
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService; //调用service接口
//查询
@GetMapping
public Result list()
{
log.info("查询全部部门数据");
//调用service查询部门数据
List<Dept> deptList = deptService.list();
return Result.success(deptList);
}
//删除
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id)
{
log.info("根据id删除部门:{}",id);
//调用service删除部门
deptService.delete(id);
return Result.success();
}
//新增
@PostMapping
public Result add(@RequestBody Dept dept)
{
log.info("新增部门:{}",dept);
//调用service新增部门
deptService.add(dept);
return Result.success();
}
//根据id查询数据
@GetMapping("/{id}")
public Result getByID(@PathVariable Integer id)
{
log.info("获取部门id:{}",id);
Dept dept = deptService.getByID(id);
return Result.success(dept);
}
//修改
@PutMapping
public Result modify(@RequestBody Dept dept)
{
log.info("修改数据:{}",dept.getId());
//调用service修改数据
deptService.modify(dept);
return Result.success();
}
}
(2)DeptService 接口
public interface DeptService {
//查询全部部门数据
List<Dept> list();
//删除部门
void delete(Integer id);
//新增部门
void add(Dept dept);
//修改部门
void modify(Dept dept);
//根据id查询部门
Dept getByID(Integer id);
}
(3)DeptServiceImpl 实现类
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper; //调用mapper接口
@Override
public List<Dept> list() {
return deptMapper.list();
}
@Override
public void delete(Integer id) {
deptMapper.deleteById(id);
}
@Override
public void add(Dept dept) {
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
deptMapper.add(dept);
}
@Override
public void modify(Dept dept) {
dept.setUpdateTime(LocalDateTime.now());
deptMapper.modify(dept);
}
@Override
public Dept getByID(Integer id) {
Dept dept = deptMapper.getByID(id);
return dept;
}
}
(4)DeptMapper类
@Mapper
public interface DeptMapper {
//查询全部部门数据
@Select("select * from dept")
List<Dept> list();
//删除数据
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
//新增数据
@Insert("insert into dept(name,create_time,update_time) values(#{name},#{createTime},#{updateTime})")
void add(Dept dept);
//修改数据
@Update("update dept set name = #{name},update_time = #{updateTime} where id = #{id}")
void modify(Dept dept);
//根据id获取部门
@Select("select * from dept where id = #{id}")
Dept getByID(Integer id);
}
四、员工管理功能开发
1、分页查询 - 原始代码
(1)复习SQL分页查询语法
select 字段列表 from 表名 limit 起始索引,查询记录数;
起始索引 = (页码 - 1)* 每页展示记录数
-- 1. 从起始索引0开始查询员工数据, 每页展示5条记录
select * from tb_emp limit 0,5;
-- 2. 查询 第1页 员工数据, 每页展示5条记录
select * from tb_emp limit 0,5;
-- 3. 查询 第2页 员工数据, 每页展示5条记录
select * from tb_emp limit 5,5;
-- 4. 查询 第3页 员工数据, 每页展示5条记录
select * from tb_emp limit 10,5;
(2)需求分析
(3)定义PageBean类
接口文档里需要返回两个数据,一个是总记录数total,一个是展示数据列表rows,我们将它们封装在一个实体类PageBean中
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {
private Long total; //总记录数
private List rows; //数据列表
}
(4)员工列表查询
接口信息:
请求参数:
注意!参数一定要和接口文档中一致,否则无法传参!
响应数据: 一个【Emp类的list表】和【Integer类的total页面总数】 封装在一个类中
(1)Controller类
① 设置请求参数默认值 @RequestParam(defaultValue="1")
//员工管理controller
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
//分页查询
@GetMapping
public Result selectByPage(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize)
{
log.info("查询数据:第{}页,{}条数据",page,pageSize);
PageBean pageBean = empService.selectByPage(page,pageSize);
return Result.success(pageBean);
}
}
(2)Service类
//分页查询
PageBean selectByPage(Integer page, Integer pageSize);
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empmapper;
//分页查询
@Override
public PageBean selectByPage(Integer page, Integer pageSize) {
Integer start = (page - 1) * pageSize;
List<Emp> rows = empmapper.selectByPage(start,pageSize);
Long total = empmapper.count();
PageBean pageBean = new PageBean(total,rows);
return pageBean;
}
}
(3)Mapper类
@Mapper
public interface EmpMapper {
//查询总记录数
@Select("select count(*) from emp")
public Long count();
//分页查询获取列表数据
@Select("select * from emp limit #{start}, #{pageSize};")
public List<Emp> selectByPage(Integer start,Integer pageSize);
}
(4)测试
2、分页插件 PageHelper
(1)引入pagehelper依赖
在pom.xml文件中引入依赖
<!--pageHelper分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
(2)Controller类
//员工管理controller
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
//分页查询
@GetMapping
public Result selectByPage(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize)
{
log.info("查询数据:第{}页,{}条数据",page,pageSize);
PageBean pageBean = empService.selectByPage(page,pageSize);
return Result.success(pageBean);
}
}
(3)Service类
//分页查询
PageBean selectByPage(Integer page, Integer pageSize);
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empmapper;
//分页查询
@Override
public PageBean selectByPage(Integer page, Integer pageSize) {
//1.设置分页参数
PageHelper.startPage(page,pageSize);
//2.执行查询
List<Emp> empList = empmapper.list(); //获取的是分页结果查询的封装类
Page<Emp> p = (Page<Emp>) empList; //进行强制转换
//3.封装PageBean对象
PageBean pageBean = new PageBean(p.getTotal(),p.getResult());
return pageBean;
}
}
(4)Mapper类
@Mapper
public interface EmpMapper {
//用pagehelper插件 - 分页查询获取列表数据
@Select("select * from emp ")
public List<Emp> list();
}
3、条件分页查询
请求参数:
日期格式的参数需要加上注解 @DataTimeFormat(pattern = "yyyy-MM-dd")
【javaweb】学习日记Day5 - 请求响应 分层解耦 IOC DI 三层架构_Roye_ack的博客-CSDN博客
(1)动态sql - 配置xml文件
【javaweb】学习日记Day9 - Mybatis 基础操作_Roye_ack的博客-CSDN博客
① 在resource文件下建包
与mapper接口同包同名,且与mapper接口名称一致
② 配置EmpMapper.xml文件
先打开mybatis中文网MyBatis中文网
点击【入门 - 探究已映射的SQL语句】
复制这些代码
<?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">
③ namespace属性名与mapper接口名全限定名一致
<?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.itroye.mapper.EmpMapper"> </mapper>
④ sql语句的id与mapper接口中方法名一致
⑤ sql语句中 resultType 返回结果类型为封装类的全限定名
⑥ 输入SQL语句并将参数改为动态
<?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.itroye.mapper.EmpMapper">
<select id="list" resultType="com.itroye.pojo.Emp">
select *
from emp
where
name like concat('%',#{name},'%')
and gender = #{gender}
and entrydate between #{begin} and #{end}
order by update_time desc
</select>
</mapper>
⑦ 对sql代码改为 动态SQL
注意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.itroye.mapper.EmpMapper">
<!--条件查询-->
<select id="list" resultType="com.itroye.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>
(2)Controller类
//员工管理controller
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
private EmpService empService;
//分页查询
@GetMapping
public Result selectByPage(@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,name,gender,begin,end);
PageBean pageBean = empService.selectByPage(page,pageSize,name,gender,begin,end);
return Result.success(pageBean);
}
}
(3)Service类
public interface EmpService {
//分页查询
PageBean selectByPage(Integer page, Integer pageSize,
String name, Short gender,LocalDate begin,LocalDate end);
}
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empmapper;
//分页查询
@Override
public PageBean selectByPage(Integer page, Integer pageSize, String name,
Short gender, LocalDate begin, LocalDate end) {
//1.设置分页参数
PageHelper.startPage(page,pageSize);
//2.执行查询
List<Emp> empList = empmapper.list(name, gender, begin, end); //获取的是分页结果查询的封装类
Page<Emp> p = (Page<Emp>) empList; //进行强制转换
//3.封装PageBean对象
PageBean pageBean = new PageBean(p.getTotal(),p.getResult());
return pageBean;
}
}
(4)Mapper类
@Mapper
public interface EmpMapper {
//用pagehelper插件 - 分页查询获取列表数据
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
}
4、删除员工
接口参数:
请求信息:
响应数据:直接Result.success()
(1)配置动态sql xml文件
遍历删除id,使用foreach标签
<!--批量删除-->
<delete id="delete">
delete
from emp
where id in
<foreach collection="ids" item="x" separator="," open="(" close=")">
#{x}
</foreach>
</delete>
(2)Controller类
//删除员工
@DeleteMapping("/{ids}")
public Result delete(@PathVariable List<Integer> ids)
{
log.info("删除员工id:{}",ids);
empService.delete(ids);
return Result.success();
}
(3)Service类
//批量删除
void delete(List<Integer> ids);
//批量删除
@Override
public void delete(List<Integer> ids) {
empmapper.delete(ids);
}
(4)Mapper类
// 批量删除
void delete(List<Integer> ids);