Web后端开发---SpringBootWeb案例【5】

Web后端开发---SpringBootWeb案例【5】

一.准备工作

1.1 需求&开发环境

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

-- 部门管理
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 '创建时间',
    update_time datetime    not null comment '修改时间'
) comment '部门表';

insert into dept (id, name, create_time, update_time)
values (1, '学工部', now(), now()),
       (2, '教研部', now(), now()),
       (3, '咨询部', now(), now()),
       (4, '就业部', 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 学工主管, 4 教研主管, 5 咨询师',
    entrydate   date comment '入职时间',
    dept_id     int unsigned comment '部门ID',
    create_time datetime         not null comment '创建时间',
    update_time datetime         not null comment '修改时间'
) comment '员工表';

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', '纪晓芙', 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', '宋远桥', 1, '16.jpg', 2, '2007-01-01', 2, now(), now()),
       (17, 'chenyouliang', '123456', '陈友谅', 1, '17.jpg', NULL, '2015-03-21', NULL, now(), now());

在这里插入图片描述

  • 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/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itcast</groupId>
    <artifactId>tlias-web-management_2013_p1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>tlias-web-management_2013_p1</name>
    <description>tlias-web-management_2013_p1</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>

        <!--web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--mybatis起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--springboot单元测试-->
        <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>

  • 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=123456

#配置mybatis的日志, 指定输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#开启mybatis的驼峰命名自动映射开关 a_column ------> aCloumn
mybatis.configuration.map-underscore-to-camel-case=true
  • Dept.java
package com.itcast.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * 部门实体类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
    private Integer id; //ID
    private String name; //部门名称
    private LocalDateTime createTime; //创建时间
    private LocalDateTime updateTime; //修改时间
}
  • Emp.java
package com.itcast.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; //ID
    private String username; //用户名
    private String password; //密码
    private String name; //姓名
    private Short gender; //性别 , 1 男, 2 女
    private String image; //图像url
    private Short job; //职位 , 1 班主任 , 2 讲师 , 3 学工主管 , 4 教研主管 , 5 咨询师
    private LocalDate entrydate; //入职日期
    private Integer deptId; //部门ID
    private LocalDateTime createTime; //创建时间
    private LocalDateTime updateTime; //修改时间
}
  • Result.java
package com.itcast.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);
    }
}

1.2 开发规范

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二.tlias智能学习辅助系统接口文档-V1.0

1. 部门管理

1.1 部门列表查询

1.1.1 基本信息

请求路径:/depts

请求方式:GET

接口描述:该接口用于部门列表数据查询

1.1.2 请求参数

1.1.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject[ ]非必须返回的数据
|- idnumber非必须id
|- namestring非必须部门名称
|- createTimestring非必须创建时间
|- updateTimestring非必须修改时间

响应数据样例:

{
  "code": 1,
  "msg": "success",
  "data": [
    {
      "id": 1,
      "name": "学工部",
      "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"
    }
  ]
}

1.2 删除部门

1.2.1 基本信息

请求路径:/depts/{id}

请求方式:DELETE

接口描述:该接口用于根据ID删除部门数据

1.2.2 请求参数

参数格式:路径参数

参数说明:

参数名类型是否必须备注
idnumber必须部门ID

请求参数样例:

/depts/1
1.2.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据

响应数据样例:

{
    "code":1,
    "msg":"success",
    "data":null
}

1.3 添加部门

1.3.1 基本信息

请求路径:/depts

请求方式:POST

接口描述:该接口用于添加部门数据

1.3.2 请求参数

格式:application/json

参数说明:

参数名类型是否必须备注
namestring必须部门名称

请求参数样例:

{
	"name": "教研部"
}
1.3.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据

响应数据样例:

{
    "code":1,
    "msg":"success",
    "data":null
}

1.4 根据ID查询

1.4.1 基本信息

请求路径:/depts/{id}

请求方式:GET

接口描述:该接口用于根据ID查询部门数据

1.4.2 请求参数

参数格式:路径参数

参数说明:

参数名类型是否必须备注
idnumber必须部门ID

请求参数样例:

/depts/1
1.4.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据
|- idnumber非必须id
|- namestring非必须部门名称
|- createTimestring非必须创建时间
|- updateTimestring非必须修改时间

响应数据样例:

{
  "code": 1,
  "msg": "success",
  "data": {
    "id": 1,
    "name": "学工部",
    "createTime": "2022-09-01T23:06:29",
    "updateTime": "2022-09-01T23:06:29"
  }
}

1.5 修改部门

1.5.1 基本信息

请求路径:/depts

请求方式:PUT

接口描述:该接口用于修改部门数据

1.5.2 请求参数

格式:application/json

参数说明:

参数名类型是否必须备注
idnumber必须部门ID
namestring必须部门名称

请求参数样例:

{
	"id": 1,
	"name": "教研部"
}
1.5.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据

响应数据样例:

{
    "code":1,
    "msg":"success",
    "data":null
}

2. 员工管理

2.1 员工列表查询

2.1.1 基本信息

请求路径:/emps

请求方式:GET

接口描述:该接口用于员工列表数据的条件分页查询

2.1.2 请求参数

参数格式:queryString

参数说明:

参数名称是否必须示例备注
name姓名
gender1性别 , 1 男 , 2 女
begin2010-01-01范围匹配的开始时间(入职日期)
end2020-01-01范围匹配的结束时间(入职日期)
page1分页查询的页码,如果未指定,默认为1
pageSize10分页查询的每页记录数,如果未指定,默认为10

请求数据样例:

/emps?name=&gender=1&begin=2007-09-01&end=2022-09-01&page=1&pageSize=10
2.1.3 响应数据

参数格式:application/json

参数说明:

名称类型是否必须默认值备注其他信息
codenumber必须响应码, 1 成功 , 0 失败
msgstring非必须提示信息
dataobject必须返回的数据
|- totalnumber必须总记录数
|- rowsobject []必须数据列表item 类型: object
|- idnumber非必须id
|- usernamestring非必须用户名
|- namestring非必须姓名
|- passwordstring非必须密码
|- entrydatestring非必须入职日期
|- gendernumber非必须性别 , 1 男 ; 2 女
|- imagestring非必须图像
|- jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师
|- deptIdnumber非必须部门id
|- createTimestring非必须创建时间
|- updateTimestring非必须更新时间

响应数据样例:

{
  "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"
      }
    ]
  }
}

2.2 删除员工

2.2.1 基本信息

请求路径:/emps/{ids}

请求方式:DELETE

接口描述:该接口用于批量删除员工的数据信息

2.2.2 请求参数

参数格式:路径参数

参数说明:

参数名类型示例是否必须备注
ids数组 array1,2,3必须员工的id数组

请求参数样例:

/emps/1,2,3
2.2.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据

响应数据样例:

{
    "code":1,
    "msg":"success",
    "data":null
}

2.3 添加员工

2.3.1 基本信息

请求路径:/emps

请求方式:POST

接口描述:该接口用于添加员工的信息

2.3.2 请求参数

参数格式:application/json

参数说明:

名称类型是否必须备注
usernamestring必须用户名
namestring必须姓名
gendernumber必须性别, 说明: 1 男, 2 女
imagestring非必须图像
deptIdnumber非必须部门id
entrydatestring非必须入职日期
jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师

请求数据样例:

{
  "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-03-07-37-38222.jpg",
  "username": "linpingzhi",
  "name": "林平之",
  "gender": 1,
  "job": 1,
  "entrydate": "2022-09-18",
  "deptId": 1
}
2.3.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据

响应数据样例:

{
    "code":1,
    "msg":"success",
    "data":null
}

2.4 根据ID查询

2.4.1 基本信息

请求路径:/emps/{id}

请求方式:GET

接口描述:该接口用于根据主键ID查询员工的信息

2.4.2 请求参数

参数格式:路径参数

参数说明:

参数名类型是否必须备注
idnumber必须部门ID

请求参数样例:

/emps/1
2.4.3 响应数据

参数格式:application/json

参数说明:

名称类型是否必须默认值备注其他信息
codenumber必须响应码, 1 成功 , 0 失败
msgstring非必须提示信息
dataobject必须返回的数据
|- idnumber非必须id
|- usernamestring非必须用户名
|- namestring非必须姓名
|- passwordstring非必须密码
|- entrydatestring非必须入职日期
|- gendernumber非必须性别 , 1 男 ; 2 女
|- imagestring非必须图像
|- jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师
|- deptIdnumber非必须部门id
|- createTimestring非必须创建时间
|- updateTimestring非必须更新时间

响应数据样例:

{
  "code": 1,
  "msg": "success",
  "data": {
    "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"
  }
}

2.5 修改员工

2.5.1 基本信息

请求路径:/emps

请求方式:PUT

接口描述:该接口用于修改员工的数据信息

2.5.2 请求参数

参数格式:application/json

参数说明:

名称类型是否必须备注
idnumber必须id
usernamestring必须用户名
namestring必须姓名
gendernumber必须性别, 说明: 1 男, 2 女
imagestring非必须图像
deptIdnumber非必须部门id
entrydatestring非必须入职日期
jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师

请求数据样例:

{
  "id": 1,
  "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-03-07-37-38222.jpg",
  "username": "linpingzhi",
  "name": "林平之",
  "gender": 1,
  "job": 1,
  "entrydate": "2022-09-18",
  "deptId": 1
}
2.5.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据

响应数据样例:

{
    "code":1,
    "msg":"success",
    "data":null
}

2.6 文件上传

2.6.1 基本信息

请求路径:/upload

请求方式:POST

接口描述:上传图片接口

2.6.2 请求参数

参数格式:multipart/form-data

参数说明:

参数名称参数类型是否必须示例备注
imagefile
2.6.3 响应数据

参数格式:application/json

参数说明:

参数名类型是否必须备注
codenumber必须响应码,1 代表成功,0 代表失败
msgstring非必须提示信息
dataobject非必须返回的数据,上传图片的访问路径

响应数据样例:

{
    "code": 1,
    "msg": "success",
    "data": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-0400.jpg"
}

3. 其他接口

3.1 登录

3.1.1 基本信息

请求路径:/login

请求方式:POST

接口描述:该接口用于员工登录Tlias智能学习辅助系统,登录完毕后,系统下发JWT令牌。

3.1.2 请求参数

参数格式:application/json

参数说明:

名称类型是否必须备注
usernamestring必须用户名
passwordstring必须密码

请求数据样例:

{
	"username": "jinyong",
    "password": "123456"
}
3.1.3 响应数据

参数格式:application/json

参数说明:

名称类型是否必须默认值备注其他信息
codenumber必须响应码, 1 成功 ; 0 失败
msgstring非必须提示信息
datastring必须返回的数据 , jwt令牌

响应数据样例:

{
  "code": 1,
  "msg": "success",
  "data": "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoi6YeR5bq4IiwiaWQiOjEsInVzZXJuYW1lIjoiamlueW9uZyIsImV4cCI6MTY2MjIwNzA0OH0.KkUc_CXJZJ8Dd063eImx4H9Ojfrr6XMJ-yVzaWCVZCo"
}
3.1.4 备注说明

用户登录成功后,系统会自动下发JWT令牌,然后在后续的每次请求中,都需要在请求头header中携带到服务端,请求头的名称为 token ,值为 登录时下发的JWT令牌。

如果检测到用户未登录,则会返回如下固定错误信息:

{
	"code": 0,
	"msg": "NOT_LOGIN",
	"data": null
}

三.部门管理

3.1 查询部门

在这里插入图片描述
在这里插入图片描述

  • DeptController.java
/**
 * 部门管理Controller
 */
@Slf4j
@RestController
public class DeptController {

    //获取日志记录对象
    //private static Logger logger = LoggerFactory.getLogger(DeptController.class);

    @Autowired //注入
    private DeptService deptService;

    /**
     * 部门列表数据查询
     *
     * @return
     */
    //@RequestMapping(value = "/depts",method = RequestMethod.GET)  //指定请求方式为get
    @GetMapping("/depts")
    public Result list() {
        //logger.info("查询部门全部数据");
        log.info("查询部门全部数据");

        //调用service查询部门数据
        List<Dept> deptList = deptService.list();

        return Result.success(deptList);
    }

}
  • DeptService.java
/**
 * 部门管理
 */
public interface DeptService {
    /**
     * 查询部门全部数据
     * @return
     */
    List<Dept> list();
}
  • DeptServiceImpl.java
@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<Dept> list() {
        return deptMapper.list();
    }
}
  • DeptMapper.java
/**
 * 部门管理
 */
@Mapper
public interface DeptMapper {
    /**
     * 查询部门全部数据
     * @return
     */
    @Select("select * from dept")
    List<Dept> list();
}

在这里插入图片描述
在这里插入图片描述

3.2 前后端联调

在这里插入图片描述
在这里插入图片描述

3.3 删除部门

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@Mapper
public interface DeptMapper {
    /**
     * 根据id删除部门
     * @param id
     */
    @Delete("delete from dept where id = #{id}")
    void deleteById(Integer id);
}
@Service
public class DeptServiceImpl implements DeptService {
    @Override
    public void delete(Integer id) {
        deptMapper.deleteById(id);
    }
}
public interface DeptService {
    /**
     * 删除部门
     * @param id
     */
    void delete(Integer id);
}
@Slf4j
@RestController
public class DeptController {
    @Autowired //注入
    private DeptService deptService;

    /**
     * 删除部门
     * @return
     */
    @DeleteMapping("/depts/{id}")
    public Result delete(@PathVariable Integer id){
        log.info("根据id删除部门:{}",id);

        //调用service根据id删除部门
        deptService.delete(id);

        return Result.success();
    }
}

在这里插入图片描述

3.4 新增部门

在这里插入图片描述
在这里插入图片描述

    /**
     * 新增部门
     * @param dept 部门接收JSON数据
     * @return
     */
    @PostMapping("/depts")
    public Result add(@RequestBody Dept dept){

        log.info("新增部门:{}", dept);

        //调用service新增部门
        deptService.add(dept);

        return Result.success();
    }
    /**
     * 新增部门
     * @param dept
     */
    void add(Dept dept);
    @Override
    public void add(Dept dept) {
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());
        deptMapper.insert(dept);
    }
    /**
     * 新增部门信息
     * @param dept
     */
    @Insert("insert into dept (name, create_time,update_time) values (#{name},#{createTime},#{updateTime})")
    void insert(Dept dept);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5 修改部门

    /**
     * 根据id查询部门数据
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public Result getDeptById(@PathVariable Integer id) {

        log.info("根据id查询部门数据:{}", id);

        //调用service根据id查询部门
        Dept dept = deptService.getDeptById(id);

        return Result.success(dept);
    }

    /**
     * 修改部门
     *
     * @param dept
     * @return
     */
    @PutMapping
    public Result update(@RequestBody Dept dept) {

        log.info("根据id修改部门:{}", dept);

        //调用service的更新部门
        deptService.updateDeptById(dept);

        return Result.success();
    }
    /**
     * 根据id查询部门
     *
     * @param id
     * @return
     */
    Dept getDeptById(Integer id);

    /**
     * 更新部门
     *
     * @param dept
     */
    void updateDeptById(Dept dept);
    @Override
    public Dept getDeptById(Integer id) {
        return deptMapper.getById(id);
    }

    @Override
    public void updateDeptById(Dept dept) {
        dept.setUpdateTime(LocalDateTime.now());
        deptMapper.updateById(dept);
    }
    /**
     * 根据id查询部门
     *
     * @param id
     * @return
     */
    @Select("select * from dept where id = #{id}")
    Dept getById(Integer id);

    /**
     * 更新部门
     *
     * @param dept
     */
    @Update("update dept set name = #{name},update_time = #{updateTime} where id=#{id}")
    void updateById(Dept dept);

在这里插入图片描述
在这里插入图片描述

3.6 小结

在这里插入图片描述

四.员工管理

在这里插入图片描述

4.1 分页查询

在这里插入图片描述
在这里插入图片描述

-- 分页查询语法
-- 参数1:起始索引 = (页码 - 1) * 每页展示的记录数
-- 参数2:查询返回记录数 = 每页展示的记录数
select * from emp limit 0,5;

-- 查询第一页数据,每页展示5条记录;
select * from emp limit 0,5;

-- 查询第二页数据,每页展示5条记录;
select * from emp limit 5,5;

-- 查询第二页数据,每页展示5条记录;
select * from emp limit 10,5;

-- 获取总记录数
select count(*) from emp;

在这里插入图片描述
在这里插入图片描述

代码

  • PageBean.java
/**
 * 分页查询结果的封装类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {

    private Long total;//总记录数
    private List rows;//数据列表
    
}
  • EmpMapper.java
/**
 * 员工管理
 */
@Mapper
public interface EmpMapper {

    /**
     * 查询总记录数
     *
     * @return
     */
    @Select("select count(*) from emp")
    public Long count();

    /**
     * 分页查询获取列表数据的方法
     * @param start
     * @param pageSize
     * @return
     */
    @Select("select * from emp limit #{start},#{pageSize}")
    public List<Emp> page(Integer start, Integer pageSize);

}
  • EmpController.java
/**
 * 员工管理Controller
 */
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {

    @Autowired
    private EmpService empService;

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping
    public Result page(@RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer pageSize) {
        log.info("分页查询,参数:{},{}", page, pageSize);

        //调用service分页查询
        PageBean pageBean = empService.page(page, pageSize);

        return Result.success(pageBean);
    }
}
  • EmpService.java
/**
 * 员工管理
 */
public interface EmpService {

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @return
     */
    PageBean page(Integer page, Integer pageSize);
}
  • EmpServiceImpl.java
@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Override
    public PageBean page(Integer page, Integer pageSize) {
        //1.获取总记录数
        Long count = empMapper.count();

        //2.获取分页查询的列表
        Integer start = (page - 1) * pageSize;
        List<Emp> empList = empMapper.page(start, pageSize);

        //3.封装pageBean对象
        PageBean pageBean = new PageBean(count,empList);

        return pageBean;
    }
}

@RequestParam defaultValue

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结

在这里插入图片描述

分页插件PageHelper

在这里插入图片描述
在这里插入图片描述

        <!--pagehelper分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.2</version>
        </dependency>
/**
 * 员工管理
 */
@Mapper
public interface EmpMapper {
    /**
     * 员工信息查询
     * @return
     */
    @Select("select * from emp")
    public List<Emp> list();

}
@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Override
    public PageBean page(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.2 条件分页查询(带条件)

在这里插入图片描述
在这里插入图片描述

-- 条件查询员工 - 姓名、性别、入职时间
select *
from emp
where name like concat('%', '张', '%')
  and gender = 1
  and entrydate between '2000-01-01' and '2020-01-01'
order by update_time desc;

在这里插入图片描述
在这里插入图片描述

    /**
     * 分页查询
     *
     * @param page
     * @param pageSize
     * @return
     */
    @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("分页查询,参数:{},{},{},{},{},{}", page, pageSize, name, gender, begin, end);

        //调用service分页查询
        PageBean pageBean = empService.page(page, pageSize, name, gender, begin, end);

        return Result.success(pageBean);
    }
    @Override
    public PageBean page(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;
    }
    /**
     * 员工信息查询
     * @return
     */
    //@Select("select * from emp")
    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
<?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.itcast.mapper.EmpMapper">

    <!--条件查询-->
    <select id="list" resultType="com.itcast.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>

在这里插入图片描述

4.3 删除员工

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    @DeleteMapping("/{ids}")
    public Result delete(@PathVariable List<Integer> ids) { //PathVariable:路径参数

        log.info("批量删除员工,参数ids:{}", ids);

        //调用service删除员工
        empService.delete(ids);

        return Result.success();
    }
    /**
     * 批量删除员工操作
     * @param ids
     */
    void delete(List<Integer> ids);
    @Override
    public void delete(List<Integer> ids) {
        empMapper.delete(ids);
    }
    /**
     * 批量删除员工操作
     * @param ids
     */
    void delete(List<Integer> ids);
    <!--批量删除员工的操作-->
    <delete id="delete">
        delete
        from emp
        where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

4.4 新增员工

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    @PostMapping
    public Result save(@RequestBody Emp emp){

        log.info("新增员工,emp:{}", emp);
        empService.save(emp);

        return Result.success();
    }
    /**
     * 新增员工
     * @param emp
     */
    void save(Emp emp);
    @Override
    public void save(Emp emp) {
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.insert(emp);
    }
    /**
     * 新增员工
     *
     * @param emp
     */
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            "values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
    void insert(Emp emp);

在这里插入图片描述

{
  "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-03-07-37-38222.jpg",
  "username": "linpingzhi",
  "name": "林平之",
  "gender": 1,
  "job": 1,
  "entrydate": "2022-09-18",
  "deptId": 1
}

在这里插入图片描述
在这里插入图片描述

4.5 文件上传

简介在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@Slf4j
@RestController
public class UploadController {

    @PostMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image) {

        log.info("文件上传:{},{},{}", username, age, image);

        return Result.success();
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
</head>
<body>

    <form action="/upload" method="post" enctype="multipart/form-data">
        姓名: <input type="text" name="username"><br>
        年龄: <input type="text" name="age"><br>
        头像: <input type="file" name="image"><br>
        <input type="submit" value="提交">
    </form>

</body>
</html>

本地存储

在这里插入图片描述

@Slf4j
@RestController
public class UploadController {

    @PostMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image) throws Exception {

        log.info("文件上传:{},{},{}", username, age, image);
        //获取原始文件名
        String originalFilename = image.getOriginalFilename();
        log.info("原始文件名:{}", originalFilename);

        //构造唯一的文件名(不能重复) - uuid(通用唯一识别码) c6b09b01-f7c6-42e2-9917-e3bc51bc72ec
        int index = originalFilename.lastIndexOf(".");
        String extname = originalFilename.substring(index);
        String newFileName = UUID.randomUUID().toString() + extname;
        log.info("新的文件名:{}", newFileName);

        //将接收到在服务器的磁盘目录 D:\images
        image.transferTo(new File("D:\\images\\" + newFileName));

        return Result.success();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

阿里云OSS–集成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        <!--阿里云OSS云存储-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.15.1</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.FileInputStream;
import java.io.InputStream;

public class AliOssTest {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        //EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        //打开CMD
        //set OSS_ACCESS_KEY_ID=LTAI4GDty8ab9W4Y1D****
        //set OSS_ACCESS_KEY_SECRET=IrVTNZNy5yQelTETg0cZML3TQn****


//        String accessKeyId = "";
//        String accessKeySecret = "";
//        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newDefaultCredentialProvider();

        // 嵌入代码
        // RAM用户的访问密钥(AccessKey ID和AccessKey Secret)。注意修改xxx的值
        String accessKeyId = "LTAI5tKyzrTK3ooL4jBSuNqY";
        String accessKeySecret = "lqn8XufEwjCmbYZLPG1IAgdiH10fp1";
        // 使用代码嵌入的RAM用户的访问密钥配置访问凭证。
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);

        // 填写Bucket名称,例如examplebucket。
        String bucketName = "web-tlias-20231216";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "file/20231216.jpg";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        String filePath= "C:\\Users\\64935\\Desktop\\壁纸\\1.jpg";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

}

在这里插入图片描述

  • AliOSSUtils【阿里云 OSS 工具类】
/**
 * 阿里云 OSS 工具类
 */
@Slf4j
@Component
public class AliOSSUtils {

    private String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    private String accessKeyId = "LTAI5tKyzrTK3ooL4jBSuNqY";
    private String accessKeySecret = "lqn8XufEwjCmbYZLPG1IAgdiH10fp1";
    private String bucketName = "web-tlias-20231216";

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile file) throws IOException {
        // 获取上传的文件的输入流
        InputStream inputStream = file.getInputStream();

        // 避免文件覆盖
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
        log.info("文件的原始名字为:{}", originalFilename);
        log.info("上传文件的名字为:{}", fileName);

        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, inputStream);

        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
        log.info("文件访问路径:{}", url);

        // 关闭ossClient
        ossClient.shutdown();

        return url;// 把上传到oss的路径返回
    }


}
  • UploadController
@Slf4j
@RestController
public class UploadController {

    @Autowired
    private AliOSSUtils aliOSSUtils;

    @PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {

        log.info("文件上传,文件名:{}", image.getOriginalFilename());

        //调用阿里云OSS工具类进行文件上传
        String url = aliOSSUtils.upload(image);
        log.info("文件上传完成,文件访问的url:{}", url);

        return Result.success(url);
    }

}

在这里插入图片描述
在这里插入图片描述

4.6 修改员工

在这里插入图片描述

查询回显

在这里插入图片描述
在这里插入图片描述

    @GetMapping("/{id}")
    public Result getById(@PathVariable Integer id) {

        log.info("根据id查询员工信息:{}", id);
        Emp emp = empService.getById(id);

        return Result.success(emp);
    }
    /**
     * 根据ID查询员工
     * @param id
     * @return
     */
    Emp getById(Integer id);
    @Override
    public Emp getById(Integer id) {
        return empMapper.getById(id);
    }
    /**
     * 根据ID查询员工
     * @param id
     * @return
     */
    @Select("select * from emp where id = #{id}")
    Emp getById(Integer id);

修改员工

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    @PutMapping
    public Result update(@RequestBody Emp emp) {

        log.info("更新员工信息:{}", emp);
        empService.update(emp);

        return Result.success();
    }
    /**
     * 更新员工
     * @param emp
     */
    void update(Emp emp);
    @Override
    public void update(Emp emp) {
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.update(emp);
    }
    /**
     * 更新员工
     * @param emp
     */
    void update(Emp emp);
    <!--更新员工-->
    <update id="update">
        update emp
        <set>
            <if test="username!=null and username!=''">
                username = #{username},
            </if>
            <if test="password!=null and password!=''">
                password = #{password},
            </if>
            <if test="name!=null and name!=''">
                name = #{name},
            </if>
            <if test="gender!=null">
                gender = #{gender},
            </if>
            <if test="image!=null and image!=''">
                image = #{image},
            </if>
            <if test="job!=null">
                job = #{job},
            </if>
            <if test="entrydate!=null">
                entrydate = #{entrydate},
            </if>
            <if test="deptId!=null">
                dept_id = #{deptId},
            </if>
            <if test="updateTime!=null">
                update_time=#{updateTime}
            </if>
        </set>
        where id = #{id};
    </update>

在这里插入图片描述
在这里插入图片描述

4.7 配置文件

参数配置化

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

yml配置文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

server:
  port: 9000

#定义对象/Map集合
user:
  name: Tom
  age: 20
  address: beijing

#数组/List/Set集合
hobby:
  - Java
  - Python
  - C
  - C++
  - html
  - css
  - web
spring:
  #数据库连接信息
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/tlias
    username: root
    password: 123456
  #文件上传的配置
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 100MB

#Mybatis配置
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

#阿里云OSS
aliyun:
  oss:
    endpoint: https://oss-cn-hangzhou.aliyuncs.com
    accessKeyId: ****************
    accessKeySecret: *************
    bucketName: web-tlias-20231216

在这里插入图片描述
在这里插入图片描述

@ConfigurationProperties

在这里插入图片描述
在这里插入图片描述

  • application.yml
#阿里云OSS
aliyun:
  oss:
    endpoint: https://oss-cn-hangzhou.aliyuncs.com
    accessKeyId: ****************************
    accessKeySecret: ****************************
    bucketName: web-tlias-20231216
  • AliOSSProperties.java
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
}
  • AliOSSUtils.java
/**
 * 阿里云 OSS 工具类
 */
@Slf4j
@Component
public class AliOSSUtils {

    @Autowired
    private AliOSSProperties aliOSSProperties;

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile file) throws IOException {

        //获取阿里云OSS参数
        String endpoint = aliOSSProperties.getEndpoint();
        String accessKeyId = aliOSSProperties.getAccessKeyId();
        String accessKeySecret = aliOSSProperties.getAccessKeySecret();
        String bucketName = aliOSSProperties.getBucketName();

        // 获取上传的文件的输入流
        InputStream inputStream = file.getInputStream();

        // 避免文件覆盖
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
        log.info("文件的原始名字为:{}", originalFilename);
        log.info("上传文件的名字为:{}", fileName);

        //fileName上传到OSS指定文件目录
        fileName = "tlias" + "/" + fileName;

        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, inputStream);

        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
        log.info("文件访问路径:{}", url);

        // 关闭ossClient
        ossClient.shutdown();

        return url;// 把上传到oss的路径返回
    }


}
  • 另一种
  • oss.properties
##阿里云OSS配置
aliyun.oss.endpoint=https://oss-cn-hangzhou.aliyuncs.com
aliyun.oss.accessKeyId=****************************
aliyun.oss.accessKeySecret=****************************
aliyun.oss.bucketName=web-tlias-20231216
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Data
@Component
@PropertySource("classpath:oss.properties")//读取阿里云配置文件
@ConfigurationProperties(prefix = "aliyun.oss")//读取oss节点
public class AliOSSProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
}

4.8 解除配置文件警告信息–提示配置信息

在这里插入图片描述

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>

在这里插入图片描述

4.9 @ConfigurationProperties与@value

在这里插入图片描述

@Data
@Component
@PropertySource("classpath:oss.properties")//读取阿里云配置文件
@ConfigurationProperties(prefix = "aliyun.oss")//读取oss节点
public class AliOSSProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
}
    @Value("${aliyun.oss.endpoint}")
    private String endpoint;
    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

五、Spring Boot整合swagger使用教程

5.1 添加依赖包

  • pom.xml
        <!--swagger 相关依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spring-web</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--Swagger ui,展示接口文档和测试页面-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

5.2 编写配置信息

  • SwaggerConfig.java
@Configuration //标明配置类
@EnableSwagger2 //开启 Swagger2 的自动配置功能
//启动下服务,输入:http://localhost:8080/swagger-ui.html# 即可查看Swagger文档
public class SwaggerConfig {
    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder().title("tlias智能学习辅助系统").build());
    }
}
@Configuration // 标明是配置类
@EnableSwagger2 //开启swagger功能
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)  // DocumentationType.SWAGGER_2 固定的,代表swagger2
//                .groupName("分布式任务系统") // 如果配置多个文档的时候,那么需要配置groupName来分组标识
                .apiInfo(apiInfo()) // 用于生成API信息
                .select() // select()函数返回一个ApiSelectorBuilder实例,用来控制接口被swagger做成文档
                .apis(RequestHandlerSelectors.basePackage("com.itcast.controller")) // 用于指定扫描哪个包下的接口
                .paths(PathSelectors.any())// 选择所有的API,如果你想只为部分API生成文档,可以配置这里
                .build();
    }

    /**
     * 用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("XX项目API") //  可以用来自定义API的主标题
                .description("XX项目SwaggerAPI管理") // 可以用来描述整体的API
                .termsOfServiceUrl("") // 用于定义服务的域名
                .version("1.0") // 可以用来定义版本。
                .build(); //
    }
}
@Bean
     public Docket docket() {
          // 创建一个 swagger 的 bean 实例
          return new Docket(DocumentationType.SWAGGER_2)
                  //配置基本信息
                  .apiInfo(apiInfo())
                  // 配置接口信息
                  .select() // 设置扫描接口
                  // 配置如何扫描接口
                  .apis(RequestHandlerSelectors
                                  //.any() // 扫描全部的接口,默认
                                  //.none() // 全部不扫描
                                  .basePackage("com.swagger.controller") // 扫描指定包下的接口,最为常用
                          //.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口
                          //.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口
 
                  )
                  .paths(PathSelectors
                                  .any() // 满足条件的路径,该断言总为true
                          //.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)
                          //.ant("/user/**") // 满足字符串表达式路径
                          //.regex("") // 符合正则的路径
                  )
                  .build();
     }

5.3 解决问题

不能调用"org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()“,因为"this.condition”为null
这个问题是由SpringBoot2.6中引入的新PathPatternParser引起的

  • application.yaml
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

在这里插入图片描述

5.4 定义接口组

@Api(tags = "用户管理") //  tags:你可以当作是这个组的名字。
@RestController
public class UserController {
}

在这里插入图片描述
在这里插入图片描述

    @ApiOperation(value = "用户测试",notes = "用户测试notes")
    @GetMapping("/test")
    public String test(String id){
        return "test";
    }

在这里插入图片描述
常用配置项:

value:可以当作是接口的简称
notes:接口的描述
tags:可以额外定义接口组,比如这个接口外层已经有@Api(tags = "用户管理"),将接口划分到了“用户管理”中,但你可以额外的使用tags,例如tags = "角色管理"让角色管理中也有这个接口文档。
在这里插入图片描述

六、登录认证

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.1 登录功能

在这里插入图片描述

  • LoginController.java
@Slf4j
@RestController
@Api(value = "登录")
public class LoginController {

    @Autowired
    private EmpService empService;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp) {
        log.info("员工登录:{}", emp);

        Emp e = empService.login(emp);

        return e != null ? Result.success() : Result.error("用户名或者密码错误");
    }
}
    /**
     * 员工登录操作
     *
     * @param emp
     * @return
     */
    Emp login(Emp emp);
    @Override
    public Emp login(Emp emp) {
        return empMapper.getByUsernameAndPassword(emp);
    }
    /**
     * 根据用户名和密码查询员工
     *
     * @param emp
     * @return
     */
    @Select("select * from emp where username = #{username} and password = #{password}")
    Emp getByUsernameAndPassword(Emp emp);

6.2 登录校验(重点)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

会话技术

在这里插入图片描述

  • SessionController.java
/**
 * Cookie , HttpSession演示
 */
@Slf4j
@RestController
@Api(value = "Cookie , HttpSession演示")
public class SessionController {

    //设置Cookie
    @GetMapping("/c1")
    public Result cookie1(HttpServletResponse response) {
        response.addCookie(new Cookie("login_username", "itcast"));  // 设置Cookie/响应Cookie
        return Result.success();
    }

    //获取Cookie
    @GetMapping("/c2")
    public Result cookie2(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies(); // 获取所有的Cookie
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("login_username")) { // 输出name为login_username 的 cookie
                System.out.println("login_username" + cookie.getValue());
            }
        }

        return Result.success();
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • SessionController.java
/**
 * Cookie , HttpSession演示
 */
@Slf4j
@RestController
@Api(value = "Cookie , HttpSession演示")
public class SessionController {

    //设置Cookie
    @GetMapping("/c1")
    public Result cookie1(HttpServletResponse response) {
        response.addCookie(new Cookie("login_username", "itcast"));  // 设置Cookie/响应Cookie
        return Result.success();
    }

    //获取Cookie
    @GetMapping("/c2")
    public Result cookie2(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies(); // 获取所有的Cookie
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("login_username")) { // 输出name为login_username 的 cookie
                System.out.println("login_username:" + cookie.getValue());
            }
        }

        return Result.success();
    }

    //往HttpSession中存储值
    @GetMapping("/s1")
    public Result session1(HttpSession session) {
        log.info("HttpSession-s1:{}", session.hashCode());

        session.setAttribute("loginUser", "tom");//往seeion中存储数据
        return Result.success();
    }

    //往HttpSession中获取值
    @GetMapping("/s2")
    public Result session2(HttpServletRequest request) {
        HttpSession session = request.getSession();
        
        log.info("HttpSession-s2:{}", session.hashCode());

        Object loginUser = session.getAttribute("loginUser"); //从session中获取数据
        log.info("loginUser:{}", loginUser);

        return Result.success(loginUser);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

JWT令牌

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
  • JwtTest.java
public class JwtTest {

    /**
     * 生成JWT
     */
    @Test
    public void testGenJwt() {
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", 1);
        claims.put("username", "Tom");
        String jwt = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "itcast") //签名算法
                .setClaims(claims) //自定义内容(载荷)
                .setExpiration(new Date(System.currentTimeMillis() + 12 * 3600 * 1000)) // 设置有效期为12小时
                .compact();
        System.out.println(jwt);
    }

    /**
     * 解析JWT
     */
    @Test
    public void testParseJwt() {
        Claims claims = Jwts.parser()
                .setSigningKey("itcast") //指定签名秘钥
                .parseClaimsJws(getJwt()) //解析令牌
                .getBody();
        System.out.println(claims);
    }

    public String getJwt() {
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", 1);
        claims.put("username", "Tom");
        String jwt = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "itcast") //签名算法
                .setClaims(claims) //自定义内容(载荷)
                .setExpiration(new Date(System.currentTimeMillis() + 12 * 3600 * 1000)) // 设置有效期为12小时
                .compact();
        System.out.println(jwt);
        return jwt;
    }

}

在这里插入图片描述
在这里插入图片描述

  • JwtUtils.java
public class JwtUtils {

    private static String signkey = "itcast";
    private static long expire = 43200000L; //12H

    /**
     * 生成JWT令牌
     *
     * @param claims JWT第二部分负载playload中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims) {
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signkey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载playload中存储的内容
     */
    public static Claims parseJWT(String jwt) {
        Claims claims = Jwts.parser()
                .setSigningKey(signkey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }

}

在这里插入图片描述

  • LoginController.java
@Slf4j
@RestController
@Api(value = "登录")
public class LoginController {

    @Autowired
    private EmpService empService;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp) {
        log.info("员工登录:{}", emp);

        Emp e = empService.login(emp);

        //登录成功,生成令牌,下发令牌
        if (e != null) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", e.getId());
            claims.put("name", e.getName());
            claims.put("username", e.getUsername());

            String jwt = JwtUtils.generateJwt(claims); //jwt包含了当前登录的员工信息

            return Result.success(jwt);
        }

        //登录失败,返回错误信息
        return Result.error("NOT_LOGIN");

        //return e != null ? Result.success() : Result.error("用户名或者密码错误");
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

过滤器Filter

在这里插入图片描述

Filter快速入门

在这里插入图片描述

  • TliasWebManagement2013P1Application.java
@ServletComponentScan //开启了对servlet组件的支持
@SpringBootApplication
public class TliasWebManagement2013P1Application {

    public static void main(String[] args) {
        SpringApplication.run(TliasWebManagement2013P1Application.class, args);
    }

}
  • DemoFilter.java
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {

    @Override //初始化方法,Web服务器启动,创建Filter时调用,只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Init 初始化方法执行了");
    }

    @Override // 拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("拦截到了请求");

    }

    @Override //销毁方法,服务器关闭时调用,只调用一次
    public void destroy() {
        System.out.println("destroy 销毁方法执行了");
    }
}

在这里插入图片描述

详解(执行流程、拦截路径、过滤器链)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

登录校验-Filter

在这里插入图片描述
在这里插入图片描述

        <!--阿里巴巴fastJSON工具包-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
  • LoginCheckFilter.java
/**
 * 登录校验过滤器的逻辑
 */
@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //1.获取请求的url
        //2.判断请求的url是否包含login,如果包含,说明是登录操作,放行。
        //3.获取请求头中的令牌(token)。
        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        //5.解析token,如果解析失败,返回错误结果(未登录)。
        //6.放行。

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        //1.获取请求的url
        String url = req.getRequestURL().toString();
        log.info("请求的url:{}", url);

        //2.判断请求的url是否包含login,如果包含,说明是登录操作,放行。
        if (url.contains("login")) {
            log.info("登录操作,放行....");
            chain.doFilter(request, response);
            return;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if (!StringUtils.hasLength(jwt)) {
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");

            //手动转换 -- json ----->阿里巴巴fastJSON工具包
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt令牌解析失败
            e.printStackTrace();
            log.info("解析令牌失败,返回未登录的错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 -- json ----->阿里巴巴fastJSON工具包
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //6.放行。
        log.info("令牌合法");
        chain.doFilter(request, response);

    }
}

拦截器Interceptor

简介&快速入门

在这里插入图片描述
在这里插入图片描述

  • LoginCheckInterceptor.java
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 定义拦截器,实现HandlerInterceptor接口,并重写其所有方法。
 */
@Component //交给IOC容器管理
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法执行前执行,返回true:放行,返回false:不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle......");
        return true;
    }

    @Override //目标资源方法执行后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle......");
    }

    @Override //视图渲染完毕后执行,最后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion......");
    }
}
  • WebConfig.java
/**
 * 注册拦截器
 */
@Configuration //配置类
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器,拦截器拦截所有资源
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
    }
}
详解(拦截路径、执行流程)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

登录校验–Interceptor

在这里插入图片描述

  • LoginCheckInterceptor.java
/**
 * 定义拦截器,实现HandlerInterceptor接口,并重写其所有方法。
 */
@Slf4j
@Component //交给IOC容器管理
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法执行前执行,返回true:放行,返回false:不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        System.out.println("preHandle......");

        //1.获取请求的url
        //2.判断请求的url是否包含login,如果包含,说明是登录操作,放行。
        //3.获取请求头中的令牌(token)。
        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        //5.解析token,如果解析失败,返回错误结果(未登录)。
        //6.放行。

        //1.获取请求的url
        String url = req.getRequestURL().toString();
        log.info("请求的url:{}", url);

        //2.判断请求的url是否包含login,如果包含,说明是登录操作,放行。
        if (url.contains("login")) {
            log.info("登录操作,放行....");
            return true;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if (!StringUtils.hasLength(jwt)) {
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 -- json ----->阿里巴巴fastJSON工具包
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt令牌解析失败
            e.printStackTrace();
            log.info("解析令牌失败,返回未登录的错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 -- json ----->阿里巴巴fastJSON工具包
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //6.放行。
        log.info("令牌合法");
        return true;
    }

    @Override //目标资源方法执行后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle......");
    }

    @Override //视图渲染完毕后执行,最后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion......");
    }
}

6.3 异常处理 【全局异常处理器】

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • GlobalExceptionHandler.java
/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class) //捕获所有的异常
    public Result ex(Exception ex){
        ex.printStackTrace();
        return Result.error("对不起,操作失败,请联系管理员");
    }

}

在这里插入图片描述

endl

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于基于Vue CLI、Element UI组件库、Axios、Spring Boot框架和Maven开发的书籍租赁系统,以下是一些可以参考的书籍和文献: 1. "Vue.js实战":作者尤雨溪,这本书详细介绍了Vue.js的核心概念和开发技巧,包括Vue CLI的使用、组件开发、路由管理等内容。它可以帮助你深入理解Vue.js的开发方式,并在项目中合理利用Vue CLI和Element UI进行开发。 2. "Spring Boot实战":作者Craig Walls,这本书介绍了Spring Boot的基本原理和使用方法,包括如何构建RESTful API、数据持久化、安全认证等内容。它可以帮助你理解Spring Boot的核心特性,并在书籍租赁系统中应用Spring Boot框架。 3. "Maven实战":作者Sonatype,这本书详细介绍了Maven的使用方法和最佳实践,包括项目依赖管理、构建配置、发布部署等内容。它可以帮助你更好地理解和应用Maven来管理你的书籍租赁系统项目。 4. "RESTful Web Services":作者Leonard Richardson和Sam Ruby,这本书深入讲解了RESTful架构的原理和设计规范,包括资源设计、URL设计、状态码、认证授权等内容。它可以帮助你设计和实现符合REST原则的后端API,以供前端调用。 除了以上的书籍,你还可以参考官方文档和教程,如Vue.js官方文档、Element UI官方文档、Spring Boot官方文档等,这些文档提供了详细的API介绍和示例代码,可以帮助你更好地理解和应用相关技术。 另外,你还可以参考一些开发者社区、技术博客和开源项目,如GitHub等,这些平台上有很多关于Vue.js、Element UI、Spring Boot和Maven的教程、案例和实战经验可供参考。通过学习和借鉴这些资源,你可以更好地开发和完善你的书籍租赁系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良辰美景好时光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值