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 /> </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 @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
开发SpringBoot程序要继承spring-boot-starter-parent
spring-boot-starter-parent中定义了若干个依赖管理
继承parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突
继承parent的形式也可以采用引入依赖的形式实现效果
starter
SpringBoot中常见项目名称,定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的
开发SpringBoot程序需要导入坐标时通常导入对应的starter
每个不同的starter根据功能不同,通常包含多个依赖坐标
使用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
内嵌Tomcat服务器是SpringBoot辅助功能之一
内嵌Tomcat工作原理是将Tomcat服务器作为对象运行,并 将该对象交给Spring容器管理
变更内嵌服务器思想是去除现有服务器,添加全新的服务器
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 spring.main.banner-mode =off logging.level.root =debug
SpringBoot内置属性查询
注意
SpringBoot中导入对应starter后,提供对应配置属性
书写SpringBoot配置采用关键字+提示形式书写
2.2 3种配置文件的格式
SpringBoot配置文件加载顺序
application.properties > application.yml > application.yaml
注意
不同配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
2.3 yaml 2.3.1 介绍 YAML(YAML Ain’t Markup Language),一种数据序列化格式
优点:
容易阅读
容易与脚本语言交互
以数据为核心,重数据轻格式
YAML文件扩展名
.yml(主流)
.yaml
2.3.2 yaml语法规则
大小写敏感
属性层级关系使用多行描述,每行结尾使用冒号结束
使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
# 表示注释
核心规则:数据前面要加空格与冒号隔开
字面值表示方式
1 2 3 4 5 6 7 8 boolean: TRUE float: 3.14 int: 123 null: ~ string: HelloWorld string2: "Hello World" date: 2018-02-17 datetime: 2018-02-17T15:02:31+08:00
数组表示方式:在属性名书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔
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 文件中
使用@Value读取单个数据,属性名引用方式:${一级属性名.二级属性名……}
封装全部数据到Environment对象
1 2 3 4 5 6 7 8 @Autowired private Environment env;System.out.println(env.getProperty("age" )); System.out.println(env.getProperty("enterprise.name" )); System.out.println(env.getProperty("enterprise.subject[0]" ));
自定义对象封装指定数据的作用
1 2 3 4 5 6 7 @Component @ConfigurationProperties(prefix = "enterprise") public class Enterprise { private String name; private Integer age; private String[] subject; }
3. 整合第三方技术 整合Junit 整合MyBatis 整合MyBatis-Plus 或者 通用Mapper 整合Druid
@SpringBootTest(测试类注解)
位置:测试类定义上方
作用:设置JUnit加载的SpringBoot启动类
1 2 3 @SpringBootTest(classes = SpringbootJUnitApplication.class) class SpringbootJUnitApplicationTests {}
注意
测试类如果存在于引导类所在包或子包中无需指定引导类
测试类如果不存在于引导类所在的包或子包中需要通过classes 属性指定引导类
如果测试类在SpringBoot启动类的包或子包中,可以省略启动类的设置,也就是省略classes的设定
整合方法
导入测试对应的starter
测试类使用@SpringBootTest修饰
使用自动装配的形式添加要测试的对象
勾选MyBatis技术,也就是导入MyBatis对应的starter
数据库连接相关信息转换成配置
数据库SQL映射需要添加@Mapper被容器识别到
引入依赖
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 >
配置信息
注意: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
定义数据层接口与映射配置
需要在引导启动类上面规定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); }
手工添加对应的starter
数据层接口使用BaseMapper简化开发
需要使用的第三方技术无法通过勾选确定时,需要手工添加坐标
手动添加坐标,引入依赖
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 >
定义数据接口与映射配置,继承BaseMapper
1 2 3 4 @Repository public interface UserMapper extends BaseMapper <User> {}
在实体类上添加@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
整合Druid需要导入Druid对应的starter
根据Druid提供的配置方式进行配置
手动添加坐标,引入依赖
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 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 模块创建
勾选SpringMVC与MySQL坐标
修改配置文件为yml格式
设置端口为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 数据层开发
导入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 >
配置数据源与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 mybatis-plus: global-config: db-config: table-prefix: tbl_ id-type: auto configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
MyBatisPlus拦截器实现
分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能, 使用MyBatisPlus拦截器实现
1 2 3 4 5 6 7 8 9 10 11 @Configuration public class MpConfig { @Bean public MybatisPlusInterceptor mpInterceptor () { MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor (); 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 ); 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>(); 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 基本开发
基于Restful制作表现层接口
新增:POST
删除:DELETE
修改:PUT
查询:GET
接收参数
实体数据:@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 异常处理
使用注解@RestControllerAdvice定义SpringMVC异常处理 器用来处理异常的
异常处理器必须被扫描加载,否则无法生效
表现层返回结果的模型类中添加消息属性用来传递消息到页面
1 2 3 4 5 6 7 8 9 10 11 @RestControllerAdvice public class ProjectExceptionAdvice { @ExceptionHandler(Exception.class) public R doOtherException (Exception ex) { ex.printStackTrace(); return new R (false ,null ,"系统错误,请稍后再试!" ); } }