1. 快速入门

1.1 基础配置

最简SpringBoot程序所包含的基础文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?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.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.jyw</groupId>
<artifactId>demo01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo04</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<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>
</plugin>
</plugins>
</build>

</project>
1
2
3
4
5
6
7
8
@SpringBootApplication
public class Demo01Application {

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

}
1
2
3
4
5
6
7
8
9
10
//Rest模式
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping
public String getById(){
System.out.println("springboot is running...");
return "springboot is running...";
}
}

Spring程序与SpringBoot程序对比

类/配置文件 Spring SpringBoot
pom文件中的坐标 手工添加 勾选添加
web3.0配置类 手工制作
Spring/SpringMVC配置类 手工制作
控制器 手工制作 手工制作

1.2 SpringBoot简介

SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程

  • Spring程序缺点
    • 依赖设置繁琐
    • 配置繁琐
  • SpringBoot程序优点
    • 起步依赖(简化依赖配置)
    • 自动配置(简化常用工程相关配置)
    • 辅助功能(内置服务器,……)

1.3 入门pom解析

parent

  1. 开发SpringBoot程序要继承spring-boot-starter-parent
  2. spring-boot-starter-parent中定义了若干个依赖管理
  3. 继承parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突
  4. 继承parent的形式也可以采用引入依赖的形式实现效果

starter

SpringBoot中常见项目名称,定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的

  1. 开发SpringBoot程序需要导入坐标时通常导入对应的starter
  2. 每个不同的starter根据功能不同,通常包含多个依赖坐标
  3. 使用starter可以实现快速配置的效果,达到简化配置的目的

对比parent

  • starter
    • SpringBoot中常见项目名称,定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的
  • parent
    • 所有SpringBoot项目要继承的项目,定义了若干个坐标版本号(依赖管理,而非依赖),以达到减少依赖冲突的目的
    • spring-boot-starter-parent各版本间存在着诸多坐标版本不同
  • 实际开发
  • 使用任意坐标时,仅书写GAV中的G和A,V由SpringBoot提供,除非SpringBoot未提供对应版本V
  • 如发生坐标错误,再指定Version(要小心版本冲突)

引导类

  • SpringBoot的引导类是Boot工程的执行入口,运行main方法就可以启动项目
  • SpringBoot工程运行后初始化Spring容器,扫描引导类所在包加载bean

内嵌tomcat

  1. 内嵌Tomcat服务器是SpringBoot辅助功能之一
  2. 内嵌Tomcat工作原理是将Tomcat服务器作为对象运行,并 将该对象交给Spring容器管理
  3. 变更内嵌服务器思想是去除现有服务器,添加全新的服务器
  • 使用maven依赖管理变更起步依赖项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--web起步依赖环境中,排除Tomcat起步依赖-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加Jetty起步依赖,版本由SpringBoot的starter控制-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependencies>
  • Jetty比Tomcat更轻量级,可扩展性更强(相较于Tomcat),谷歌应用引擎(GAE)已经全面切换为Jetty

内置服务器

tomcat(默认) apache出品,粉丝多,应用面广,负载了若干较重的组件

jetty 更轻量级,负载性能远不及tomcat

undertow undertow,负载性能勉强跑赢tomcat

2. 基础配置

2.1 application.properties

修改配置 application.properties

1
2
3
4
5
6
7
8
#修改服务器端口
server.port=80

#关闭运行日志图标(banner)
spring.main.banner-mode=off

#设置日志相关
logging.level.root=debug

SpringBoot内置属性查询

注意

  1. SpringBoot中导入对应starter后,提供对应配置属性
  2. 书写SpringBoot配置采用关键字+提示形式书写

2.2 3种配置文件的格式

  • application.properties
1
server.port=80
  • application.yml(主流)
1
2
server:
port: 81
  • application.yaml
1
2
server:
port: 82

SpringBoot配置文件加载顺序

application.properties > application.yml > application.yaml

注意

不同配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留

2.3 yaml

2.3.1 介绍

YAML(YAML Ain’t Markup Language),一种数据序列化格式

优点:

  1. 容易阅读
  2. 容易与脚本语言交互
  3. 以数据为核心,重数据轻格式

YAML文件扩展名

  1. .yml(主流)
  2. .yaml

2.3.2 yaml语法规则

  • 大小写敏感
  • 属性层级关系使用多行描述,每行结尾使用冒号结束
  • 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
  • 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
  • # 表示注释
  • 核心规则:数据前面要加空格与冒号隔开

字面值表示方式

1
2
3
4
5
6
7
8
boolean: TRUE                       #TRUE,true,True,FALSE,false,False均可
float: 3.14 #6.8523015e+5 #支持科学计数法
int: 123 #0b1010_0111_0100_1010_1110 #支持二进制、八进制、十六进制
null: ~ #使用~表示null
string: HelloWorld #字符串可以直接书写
string2: "Hello World" #可以使用双引号包裹特殊字符
date: 2018-02-17 #日期必须使用yyyy-MM-dd格式
datetime: 2018-02-17T15:02:31+08:00 #时间和日期之间使用T连接,最后使用+代表时区

数组表示方式:在属性名书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
subject:
- Java
- 前端
- 大数据
enterprise:
name: itcast
age: 16
subject:
- Java
- 前端
- 大数据
likes: [王者荣耀,刺激战场] #数组书写缩略格式

users: #对象数组格式
- name: Tom
age: 4
- name: Jerry
age: 5
users: #对象数组格式二
-
name: Tom
age: 4
-
name: Jerry
age: 5
users2: [ { name:Tom , age:4 } , { name:Jerry , age:5 } ] #对象数组缩略格式

2.3.3 yaml数据读取

在配置文件中

使用属性名引用方式引用属性

1
2
3
4
5
baseDir: /usr/local/fire
center:
dataDir: ${baseDir}/data

lesson: "Spring\tboot\nlesson" #属性值中如果出现转义字符,需要使用双引号包裹

在java 文件中

  1. 使用@Value读取单个数据,属性名引用方式:${一级属性名.二级属性名……}

  2. 封装全部数据到Environment对象

    1
    2
    3
    4
    5
    6
    7
    8
    //使用自动装配注入Environment对象
    @Autowired
    private Environment env;

    //使用对象的getProperty
    System.out.println(env.getProperty("age"));
    System.out.println(env.getProperty("enterprise.name"));
    System.out.println(env.getProperty("enterprise.subject[0]"));
  3. 自定义对象封装指定数据的作用

    1
    2
    3
    4
    5
    6
    7
    @Component//要启用spring的管理才能实现
    @ConfigurationProperties(prefix = "enterprise")//读取配置文件中前缀为enterprise的数据
    public class Enterprise {
    private String name;
    private Integer age;
    private String[] subject;
    }

3. 整合第三方技术

@SpringBootTest(测试类注解)

位置:测试类定义上方

作用:设置JUnit加载的SpringBoot启动类

1
2
3
@SpringBootTest(classes = SpringbootJUnitApplication.class)
class SpringbootJUnitApplicationTests {
}

注意

  1. 测试类如果存在于引导类所在包或子包中无需指定引导类
  2. 测试类如果不存在于引导类所在的包或子包中需要通过classes 属性指定引导类
  3. 如果测试类在SpringBoot启动类的包或子包中,可以省略启动类的设置,也就是省略classes的设定

整合方法

  1. 导入测试对应的starter
  2. 测试类使用@SpringBootTest修饰
  3. 使用自动装配的形式添加要测试的对象
  1. 勾选MyBatis技术,也就是导入MyBatis对应的starter
  2. 数据库连接相关信息转换成配置
  3. 数据库SQL映射需要添加@Mapper被容器识别到
  1. 引入依赖
1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
  1. 配置信息

注意:SpringBoot版本低于2.4.3(不含),Mysql驱动版本大于8.0时,需要在url连接串中配置时区

jdbc:mysql://localhost:3306/kangan?serverTimezone=UTC

1
2
3
4
5
6
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///kangan
username: root
password: root
  1. 定义数据层接口与映射配置

需要在引导启动类上面规定mapper空间

1
2
3
4
5
6
7
@SpringBootApplication
@MapperScan("cn.jyw.demo03.mapper")
public class Demo03Application {
public static void main(String[] args) {
SpringApplication.run(Demo03Application.class);
}
}

或者

在mapper接口层上添加@Mapper注解

1
2
3
4
@Mapper
public interface UserMapper {
User findById(Integer id);
}
  1. 手工添加对应的starter
  2. 数据层接口使用BaseMapper简化开发
  3. 需要使用的第三方技术无法通过勾选确定时,需要手工添加坐标
  1. 手动添加坐标,引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
      <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<!--或者-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
  1. 定义数据接口与映射配置,继承BaseMapper
1
2
3
4
@Repository
public interface UserMapper extends BaseMapper<User> {

}
  1. 在实体类上添加@Table 注解标注是数据库里的那一张表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@Table(name = "t_user")
public class User {

@Id
private Integer id;
private Date birthday;
private String gender;
private String username;
private String password;
private String remark;
private String station;
private String telephone;


public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}


public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}


public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}


public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}


public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}


public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}


public String getStation() {
return station;
}

public void setStation(String station) {
this.station = station;
}


public String getTelephone() {
return telephone;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

}

其他同MyBatis

  1. 整合Druid需要导入Druid对应的starter
  2. 根据Druid提供的配置方式进行配置
  1. 手动添加坐标,引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>

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

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#变更Druid的配置方式 ()
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///kangan
username: root
password: root
#指定数据源类型 不推荐
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///kangan
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource

整合第三方技术通用方式

  • 导入对应的starter
  • 根据提供的配置格式,配置非默认值对应的配置项

4. 基于SpringBoot的SSMP整合

4.1 模块创建

  1. 勾选SpringMVC与MySQL坐标
  2. 修改配置文件为yml格式
  3. 设置端口为80方便访问

4.2 实体类的开发

Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发(可以在创建模块的时候勾选上)

1
2
3
4
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

常用注解:@Data

为当前实体类在编译期设置对应的get/set方法,toString方法,hashCode方法,equals方法等

但是构造方法不在@Data内

1
2
3
4
5
6
7
@Data
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}

4.3 数据层开发

  1. 导入MyBatisPlus与Druid对应的starter
1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
  1. 配置数据源与MyBatisPlus对应的基础配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?servierTimezone=UTC
username: root
password: root

#为方便调试可以开启MyBatisPlus的日志
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_ #手动添加前缀 方便后面不用写前缀
id-type: auto #id生成策略使用数据库自增策略
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #为方便调试可以开启MyBatisPlus的日志

MyBatisPlus拦截器实现

分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能, 使用MyBatisPlus拦截器实现

1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpInterceptor() {
//1.定义Mp拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2.添加具体的拦截器
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mpInterceptor;
}
}

分页操作需要设定分页对象IPage

1
2
3
4
5
6
7
8
9
10
@Test
void testGetPage(){
IPage page = new Page(1,5);//在MP里已经有IPage对象了
bookDao.selectPage(page,null);
System.out.println(page.getCurrent());//当前页码值
System.out.println(page.getSize());//每页数据总量
System.out.println(page.getTotal());//数据总量
System.out.println(page.getPages());//最大页码值
System.out.println(page.getRecords());//数据
}

使用QueryWrapper对象封装查询条件,推荐使用LambdaQueryWrapper对象,所有查询操作封装成方法调用

支持动态拼写查询条件

1
2
3
4
5
6
7
8
9
@Test
void testGetByCondition(){
String name="Spring";
IPage page = new Page(1,10);
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
//like操作 判断拼接条件 对应的字段名称 条件
lqw.like(Strings.isNotEmpty(name),Book::getName,name);
bookDao.selectPage(page,lqw);
}

QueryWrapper 也可以这样做 但是没有 LambdaQueryWrapper安全

1
2
3
4
5
6
@Test
void testGetByCondition(){
QueryWrapper<Book> qw = new QueryWrapper<Book>();
qw.like("name","Spring");
bookDao.selectList(qw);
}

4.4 业务层开发

4.4.1 基本开发

定义接口

1
2
3
4
5
6
7
8
public interface BookService {
boolean save(Book book);
boolean delete(Integer id);
boolean update(Book book);
Book getById(Integer id);
List<Book> getAll();
IPage<Book> getByPage(int currentPage,int pageSize);
}

实现类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;

public Boolean save(Book book) {
return bookDao.insert(book) > 0;
}
public Boolean delete(Integer id) {
return bookDao.deleteById(id) > 0;
}
public Boolean update(Book book) {
return bookDao.updateById(book) > 0;
}
public Book getById(Integer id) {
return bookDao.selectById(id);
}
public List<Book> getAll() {
return bookDao.selectList(null);
}
public IPage<Book> getByPage(int currentPage, int pageSize) {
IPage page = new Page<Book>(currentPage,pageSize);
return bookDao.selectPage(page,null);
}
}

4.4.2 业务层开发————快速开发

快速开发方案

  • 使用MyBatisPlus提供有业务层通用接口(ISerivce)与业务层通用实现类(ServiceImpl)
  • 使用通用接口(ISerivce<T>)快速开发Service
  • 使用通用实现类(ServiceImpl<M,T>)快速开发ServiceImpl
  • 在通用类基础上做功能重载或功能追加
  • 注意重载时不要覆盖原始操作,避免原始提供的功能丢失

接口定义

1
2
3
4
5
6
7
public interface IBookService extends IService\<book> {
//追加的操作与原始操作通过名称区分,功能类似
Boolean delete(Integer id);
Boolean insert(Book book);
Boolean modify(Book book);
Book get(Integer id);
}

实现类追加功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Service
public class BookServiceImpl2 extends ServiceImpl<BookDao,Book> implements IBookService {
@Autowired
private BookDao bookDao;
public Boolean insert(Book book) {
return bookDao.insert(book) > 0;
}
public Boolean modify(Book book) {
return bookDao.updateById(book) > 0;
}
public Boolean delete(Integer id) {
return bookDao.deleteById(id) > 0;
}
public Book get(Integer id) {
return bookDao.selectById(id);
}
}

4.5 表现层开发

4.5.1 基本开发

  1. 基于Restful制作表现层接口
    • 新增:POST
    • 删除:DELETE
    • 修改:PUT
    • 查询:GET
  2. 接收参数
    • 实体数据:@RequestBody
    • 路径变量:@PathVariable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private IBookService bookService;
@GetMapping
public List<Book> getAll(){
return bookService.list();
}
@PostMapping
public Boolean save(@RequestBody Book book){
return bookService.insert(book);
}
@PutMapping
public Boolean update(@RequestBody Book book){
return bookService.modify(book);
}
@DeleteMapping("/{id}")
public Boolean delete(@PathVariable Integer id){
return bookService.delete(id);
}
@GetMapping("/{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById(id);
}
@GetMapping
public List<Book> getAll(){
return bookService.list();
}
@GetMapping("/{currentPage}/{pageSize}")
public List<Book> getAll(@PathVariable Integer currentPage,@PathVariable Integer pageSize,Book book){
IPage<Book> page = bookService.getPage(currentPage, pageSize,book);
//如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
if( currentPage > page.getPages()){
page = bookService.getPage((int)page.getPages(), pageSize,book);
}
}
}

4.5.2 表现层消息一致性处理

设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议

1
2
3
4
5
6
7
8
9
10
11
12
@Data
public class R{
private Boolean flag;
private Object data;
private String msg;

public R(Boolean flag,Object data,String msg){
this.flag = flag;
this.data = data;
this.msg = msg;
}
}

可以在表现层Controller中进行消息统一处理

1
2
3
4
5
@PostMapping
public R save(@RequestBody Book book) throws IOException {
Boolean flag = bookService.insert(book);
return new R(flag ,null, flag ? "添加成功^_^" : "添加失败-_-!");
}

页面消息处理,没有传递消息加载默认消息,传递消息后加载指定消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//添加
handleAdd () {
//发送ajax请求
axios.post("/books",this.formData).then((res)=>{
//如果操作成功,关闭弹层,显示数据
if(res.data.flag){
this.dialogFormVisible = false;
this.$message.success(res.data.msg);
}else {
this.$message.error(res.data.msg);
}
}).finally(()=>{
this.getAll();
});
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 删除
handleDelete(row) {
//1.弹出提示框
this.$confirm("此操作永久删除当前数据,是否继续?","提示",{
type:'info'
}).then(()=>{
//2.做删除业务
axios.delete("/books/"+row.id).then((res)=>{
//如果操作成功,关闭弹层,显示数据
if(res.data.flag){
this.dialogFormVisible = false;
this.$message.success(res.data.msg);
}else {
this.$message.error(res.data.msg);
}
}).finally(()=>{
this.getAll();
});
}).catch(()=>{
//3.取消删除
this.$message.info("取消删除操作");
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//弹出编辑窗口
handleUpdate(row) {
axios.get("/books/"+row.id).then((res)=>{
if(res.data.flag && res.data.data != null ){
this.dialogFormVisible4Edit = true;
this.formData = res.data.data;
}else{
this.$message.error(res.data.msg);
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
},

//修改
handleEdit() {
axios.put("/books",this.formData).then((res)=>{
//判断当前操作是否成功
if(res.data.flag){
//1.关闭弹层
this.dialogFormVisible4Edit = false;
this.$message.success(res.data.msg);
}else{
this.$message.error(res.data.msg);
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
},

4.5.3 分页条件查询

条件封装

1
2
3
4
5
6
7
8
pagination: { //分页相关模型数据
currentPage: 1, //当前页码
pageSize:10, //每页显示的记录数
total:0, //总记录数
name: "",
type: "",
description: ""
}

页面数据模型绑定

1
2
3
4
5
6
7
<div class="filter-container">
<el-input placeholder="图书类别" v-model="pagination.type" class="filter-item"/>
<el-input placeholder="图书名称" v-model="pagination.name" class="filter-item"/>
<el-input placeholder="图书描述" v-model="pagination.description" class="filter-item"/>
<el-button @click="getAll()" class="dalfBut">查询</el-button>
<el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>
</div>

组织数据成为get请求发送的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
getAll() {
//1.获取查询条件,拼接查询条件
param = "?name="+this.pagination.name;
param += "&type="+this.pagination.type;
param += "&description="+this.pagination.description;
console.log("-----------------"+ param);
axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param)
.then((res) => {
this.pagination.total = res.data.data.total;
this.pagination.currentPage = res.data.data.current;
this.pagination.pagesize = res.data.data.size;
this.dataList = res.data.data.records;
});
},

Controller接收参数

1
2
3
4
5
6
7
8
@GetMapping("/{currentPage}/{pageSize}")
public List<Book> getAll(@PathVariable Integer currentPage,@PathVariable Integer pageSize,Book book){
IPage<Book> page = bookService.getPage(currentPage, pageSize,book);
//如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
if( currentPage > page.getPages()){
page = bookService.getPage((int)page.getPages(), pageSize,book);
}
}

业务层接口功能开发

1
2
3
4
5
6
7
8
9
10
11
12
@Service
public class BookServiceImpl2 extends ServiceImpl<BookDao,Book> implements IBookService {
public IPage<Book> getPage(Integer currentPage,Integer pageSize,Book queryBook){
IPage page = new Page(currentPage,pageSize);
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
lqw.like(Strings.isNotEmpty(queryBook.getName()),Book::getName,queryBook.getName());
lqw.like(Strings.isNotEmpty(queryBook.getType()),Book::getType,queryBook.getType());
lqw.like(Strings.isNotEmpty(queryBook.getDescription()),
Book::getDescription,queryBook.getDescription());
return bookDao.selectPage(page,lqw);
}
}

4.5.4 异常处理

  1. 使用注解@RestControllerAdvice定义SpringMVC异常处理 器用来处理异常的
  2. 异常处理器必须被扫描加载,否则无法生效
  3. 表现层返回结果的模型类中添加消息属性用来传递消息到页面
1
2
3
4
5
6
7
8
9
10
11
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class)
public R doOtherException(Exception ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
ex.printStackTrace();
return new R(false,null,"系统错误,请稍后再试!");
}
}