准备工作
需求:部门管理的查询、新增、修改、删除
使用REST风格的URL:
- GET : 查询
- POST :新增
- PUT : 修改
- DELETE :删除
调试工具:Apifox
集成了Api文档、Api调试、Api Mock、Api测试的一体化协作平台。
工程搭建
创建SpringBoot工程,并引入web开发起步依赖、mybatis、mysql驱动、lombok。
创建tlias数据库,并准备dept部门表。
CREATE TABLE dept (
id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'ID, 主键',
name varchar(10) NOT NULL UNIQUE COMMENT '部门名称',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_time datetime DEFAULT NULL COMMENT '修改时间'
) COMMENT '部门表';
INSERT INTO dept VALUES (1,'学工部','2023-09-25 09:47:40','2024-07-25 09:47:40'),
(2,'教研部','2023-09-25 09:47:40','2024-08-09 15:17:04'),
(3,'咨询部','2023-09-25 09:47:40','2024-07-30 21:26:24'),
(4,'就业部','2023-09-25 09:47:40','2024-07-25 09:47:40'),
(5,'人事部','2023-09-25 09:47:40','2024-07-25 09:47:40'),
(6,'行政部','2023-11-30 20:56:37','2024-07-30 20:56:37');
在application.yml中配置数据库连接信息
spring:
application:
name: tlias-web-management
#mysql连接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tlias
username: root
password: 1234
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
准备包结构,引入实体类Dept及统一的响应结果封装类Result
实体类Dept:(lombok有问题,重写了getter、setter)
package com.baichu.poji;
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;
// Getter and Setter for id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
// Getter and Setter for name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// Getter and Setter for createTime
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
// Getter and Setter for updateTime
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
// toString method
@Override
public String toString() {
return "Dept{" +
"id=" + id +
", name='" + name + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
}
统一响应结果Result
package com.baichu.poji;
import lombok.Data;
import java.io.Serializable;
/**
* 后端统一返回结果
*/
@Data
public class Result {
private Integer code; //编码:1成功,0为失败
private String msg; //错误信息
private Object data; //数据
// 无参构造函数
public Result() {
}
// Getter and Setter for code
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
// Getter and Setter for msg
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
// Getter and Setter for data
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static Result success() {
Result result = new Result();
result.code = 1;
result.msg = "success";
return result;
}
public static Result success(Object object) {
Result result = new Result();
result.data = object;
result.code = 1;
result.msg = "success";
return result;
}
public static Result error(String msg) {
Result result = new Result();
result.msg = msg;
result.code = 0;
return result;
}
@Override
public String toString() {
return String.format(
"Result{code=%d, msg='%s', data=%s}",
code, msg,
(data != null) ? data.toString() : "null"
);
}
}
DeptMapper
package com.itheima.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DeptMapper {
}
DeptService
package com.itheima.service;
public interface DeptService {
}
DeptServiceImpl
package com.itheima.service.impl;
import com.itheima.service.DeptService;
import org.springframework.stereotype.Service;
@Service
public class DeptServiceImpl implements DeptService {
}
DeptController
package com.itheima.controller;
import org.springframework.web.bind.annotation.RestController;
/**
* 部门管理控制器
*/
@RestController
public class DeptController {
}
增删改查
查询部门
需求:查询所有的部门数据,查询出来展示在部门管理的页面中。
Controller层
/**
* 查询部门列表
* @return
*/
//@RequestMapping(value = "/depts",method = RequestMethod.GET)
@GetMapping("/depts")
public Result list(){
log.info("查询全部部门数据");
//System.out.println("查询全部部门数据");
List<Dept> deptlist = deptService.findAll();
return Result.success(deptlist);
}
Service层
在 DeptService 中,增加 findAll方法
List<Dept> findAll();
在 DeptServiceImpl 中,增加 findAll方法
@Override
public List<Dept> findAll() {
return deptMapper.findAll();
}
Mapper层
在 DeptMapper 中,增加 findAll方法
@Select("select id, name, create_time createTime,update_time updateTime from dept order by create_time desc")
List<Dept> findAll();
接口测试
删除部门
删除部门数据。在点击 “删除” 按钮,会根据ID删除部门数据。
Controller层
/**
* 删除部门
*/
@DeleteMapping("/depts")
public Result delete(Integer id){
log.info("根据id删除部门"+id);
deptService.deleteById(id);
return Result.success();
}
Service层
在 DeptService 中,增加 deleteById 方法
void deleteById(Integer id);
在 DeptServiceImpl 中,增加 deleteById 方法
@Override
public void deleteById(Integer id) {
deptMapper.deleteById(id);
}
Mapper层
在 DeptMapper 中,增加 deleteById 方法
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
接口测试
新增部门
点击 “新增部门” 的按钮之后,弹出新增部门表单,填写部门名称之后,点击确定之后,保存部门数据。
Controller层
/**
* 增加部门
*/
@PostMapping("/depts")
public Result add(@RequestBody Dept dept){
log.info("增加部门");
deptService.add(dept);
return Result.success();
}
Service层
在 DeptService 中,增加 deleteById 方法
void add(Dept dept);
在 DeptServiceImpl 中,增加 deleteById 方法
@Override
public void add(Dept dept) {
dept.setUpdateTime(LocalDateTime.now());
dept.setCreateTime(LocalDateTime.now());
deptMapper.insert(dept);
}
Mapper层
在 DeptMapper 中,增加 deleteById 方法
@Insert("insert into dept(name, create_time, update_time) values (#{name},#{createTime},#{updateTime})")
void insert(Dept dept);
接口测试
修改部门
对于任何业务的修改功能来说,一般都会分为两步进行:查询回显、修改数据。
查询回显
当我们点击 “编辑” 的时候,需要根据ID查询部门数据,然后用于页面回显展示。
Controller层
/**
* 根据id查找
* @param id
* @return
*/
@GetMapping("/depts/{id}")
public Result getInfo(@PathVariable Integer id){
log.info("根据id查找部门:"+id);
Dept dept = deptService.getInfo(id);
return Result.success(dept);
}
Service层
在 DeptService 中增加 getById方法
Dept getInfo(Integer id);
在 DeptServiceImpl 中增加 getById方法
@Override
public Dept getInfo(Integer id) {
return deptMapper.getInfo(id);
}
Mapper层
在 DeptMapper 中增加 getById 方法
@Select("select id, name, create_time createTime,update_time updateTime from dept where id = #{id}")
Dept getInfo(Integer id);
修改数据
查询回显回来之后,就可以对部门的信息进行修改了,修改完毕之后,点击确定,此时,就需要根据ID修改部门的数据。
Controller层
/**
* 修改部门
*/
@PutMapping("/depts")
public Result upDate(@RequestBody Dept dept){
log.info("修改部门");
deptService.upDate(dept);
return Result.success();
}
Service层
在 DeptService 中增加 update 方法。
void upDate(Dept dept);
在 DeptServiceImpl 中增加 update 方法。 由于是修改操作,每一次修改数据,都需要更新updateTime。
@Override
public void upDate(Dept dept) {
dept.setUpdateTime(LocalDateTime.now());
deptMapper.update(dept);
}
Mapper层
在 DeptMapper 中增加 update 方法
@Update("update dept set name = #{name},update_time = #{updateTime} where id = #{id}")
void update(Dept dept);
接口测试
日志技术
日志框架:
- JUL:这是JavaSE平台提供的官方日志框架,也被称为JUL。配置相对简单,但不够灵活,性能较差。
- Log4j:一个流行的日志框架,提供了灵活的配置选项,支持多种输出目标。
- Logback:基于Log4j升级而来,提供了更多的功能和配置选项,性能由于Log4j。
- Slf4j:(Simple Logging Facade for Java)简单日志门面,提供了一套日志操作的标准接口及抽象类,允许应用程序使用不同的底层日志框架。
引入配置文件 logback.xml:
<configuration>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%logger显示日志记录器的名称, %msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 系统文件输出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名, %i表示序号 -->
<FileNamePattern>D:/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<!-- 最多保留的历史日志文件数量 -->
<MaxHistory>30</MaxHistory>
<!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>