【随风雨落散天涯】:做自己就好。
spring boot入门案例
- springboot是由Pivotal团队提供的全新的框架,其设计目的是用来简化spring应用的初始搭建以及开发过程
1、idea构建springboot项目如下:
2、创建控制器类
3、启动SpringbootApplication类
spring程序与springboot程序对比
类/配置文件 | Spring | springboot |
---|---|---|
pom文件的坐标 | 手工 添加 | 勾选 添加 |
web3.0配置类 | 手工添加 | 无 |
Spring/springmvc的配置类 | 手工制作 | 无 |
控制器 | 手工制作 | 手工制作 |
小结:
- 开发springboot程序可以根据向导进行联网制作
- springboot程序需要基于jdk8进行制作
- springboot程序中需要使用 何种功能通过勾选选择技术
- 运行springboot程序通过运行application程序入口进行
教你一招:隐藏文件或文件夹
springboot入门案例解析
1、springboot程序优点
起步依赖(简化依赖配置)
自动配置(简化常用工程相关 配置)
辅助功能(内置服务器等)
2、pom文件中的<parent>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
- 开发springboot程序要集成spring-boot-starter-parent
- spring-boot-starter-parent中定义了若干个依赖管理
- 集成parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突
- 继承parent的形式也可以采用引入依赖的形式实现效果
3、pom文件中的starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 当我们引入spring-boot-starter-web的依赖的时候,starter中会帮我们引入spring-webmvc、spring-web、spring-boot-starter-tomcat等要用的功能依赖
- springboot中常见的项目名称,定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的
4、引导类springbootApplication.class
@SpringBootApplication
public class Springbootdemo001Application {
public static void main(String[] args) {
SpringApplication.run(Springbootdemo001Application.class, args);
}
}
- springboot的引导类是boot工程的执行入口,运行main方法就可以启动项目
- springboot工程运行后初始化spring容器,扫描引导类所在包加载bean
5、辅助功能内嵌的tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.7.9</version>
<scope>compile</scope>
</dependency>
- 使用maven依赖管理变更起步依赖项
<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>
- jetty比tomcat更轻量级,可扩展性更强(相较于tomcat),谷歌应用引擎已经全面切换为jetty
- 内置服务器
–tomcat(默认) apache出品,粉丝多,应用面广,负载了若干较重的组件
–jetty 更轻量级,负载性能远不及tomcat
–undertow 负载性能勉强能跑赢tomcat - 内嵌tomcat是springboot辅助功能之一
- 内嵌tomcat工作原理是将tomcat服务器作为对象运行,并将该对象交给spring容器管理
- 变更内嵌服务器思想是去除现有服务器,添加全新的服务器
springboot REST风格
- REST(Representational State Transfer),表现形式状态转换
1)传统风格资源描述形式
–http://localhost/user/getById?id=1
–http://localhost/user/saveUser
2)REST风格描述形式
–http://localhost/user/1
–http://localhost/user - 优点
–隐藏资源的访问行为,无法通过地址得知对资源是何种操作
–书写简化
- 按照REST风格访问资源时使用行为动作区分对资源进行了何种操作
> http://localhost/users 查询全部用户信息 GET(查询)
> http://localhost/users/1 查询指定用户信息 GET(查询)
> http://localhost/users 添加用户信息 POST(新增、保存)
> http://localhost/users 修改用户信息 PUT(修改、更新)
> http://localhost/users/1 删除用户信息 DELETE(删除)
注意事项:
>> 上述行是约定方式,约定不是规范,可以打破,所以称为REST风格,而不是REST规范
>> 描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts…
相关注解
区别:
1、@requestParam用于接收url地址传参或表单传参
2、@requestBody用于接收json数据
3、@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
应用:
1、后期开发中发送请求参数超过1个,以json格式为主,@RequestBody应用较广
2、如果发送非json格式数据,选用@RequestParam接收请求参数
3、采用RESTful进行开发,当参数数量较少时,例如一个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
案例:
- 1、设置http请求动作
- 2、设置请求参数(路径变量)
@Controller
public class UserController {
//添加请求
@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponseBody
public String save() {
System.out.println("user safe");
return "{'module':'user save'}";
}
//删除请求
@ResponseBody
@RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)
public String delete(@PathVariable Integer id) {
System.out.println("users delete" + id);
return "{'module':'user delete'}";
}
//更新请求
@ResponseBody
@RequestMapping(value = "/users", method = RequestMethod.PUT)
public String put(@RequestBody User user) {
System.out.println("user update" + user);
return "{'module':'user update'}";
}
//根据id查询请求
@ResponseBody
@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
public String getById(@PathVariable Integer id) {
System.out.println("user getById" + id);
return "{'module':'user get'}";
}
//查询请求(所有)
@ResponseBody
@RequestMapping(value = "/users", method = RequestMethod.GET)
public String getAll() {
System.out.println("user getAll");
return "{'module':'user getaLL'}";
}
}
springboot基础配置
1、属性配置
- 修改服务器端口
server.port=8080
2、springboot提供了多种属性配置方式
- application.properties
server.port=80 - application.yml
server:
port:81 - applicaiton.yaml
server:
port:82
3、springboot配置文件加载顺序
application. properties > application.yml > application.yaml
不同配置文件中相同的配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
4、属性提示消失解决办法
5、yaml数据格式
-
YAML,是一种数据序列化格式
-
优点:
–容易阅读
–容易与脚本语言交互
–以数据为核心,重数据轻格式 -
基本语法
-
数据类型
-
示例:
public class Person {
private String userName;
private Boolean boss;
private Date birth;
private Integer age;
private Pet pet;
private String[] interests;
private List<String> animal;
private Map<String,Object> score;
private Set<Double> salarys;
private Map<String,List<Pet>> allPets;
}
//宠物类
public class Pet {
private String name;
private Double weight;
}
person:
boss: false
birth: 2019/12/12 20:12:33
age: 18
pet:
name: tomcat
weight: 23.4
interests: [篮球,游泳]
animal:
- jerry
- mario
score:
english:
first: 30
second: 40
third: 50
math: [131,140,148]
chinese: {first: 128,second: 136}
salarys: [3999,4999.98,5999.99]
allPets:
sick:
- {name: tom}
- {name: jerry,weight: 47}
health: [{name: mario,weight: 47}]
6、读取yaml单一属性数据
使用@Value读取单个数据,属性名引用方式:${一级属性名.二级属性名…}
@RestController
@RequestMapping("/books")
public class TestController {
@Value("${country}")//绑定application.yml中country的值
private String country1;
@Value("${likes[1]}")//绑定数组中的第二个值
private String like;
@Value("${users[1].age}") //绑定集合中的第二个对象的年龄
private String age;
@GetMapping
public String getId(){
System.out.println("spring boot is running..");
System.out.println("cuuntry1:"+country1);
System.out.println("like:"+like);
System.out.println("age:"+age);
return "spring boot is running ";
}
}
7、yaml文件中的变量引用
- 在配置文件中可以使用属性名引用方式引用属性
baseDir: c:\windows
#adcDir: c:\windows\temp
#使用${属性名}引用数据
adcDir: ${baseDir}\temp
- 属性中如果被双引号包裹,转义字符则将生效
#使用引号包裹的字符串,其中的转义字符\t可以生效
abd: "${baseDir}\temp\t1\t2"
8、读取yaml全部属性数据
- yaml数据读取,封装全部数据到Environment对象
@RestController
@RequestMapping("/books")
public class TestController {
@Autowired
private Environment environment;//封装了yaml中的全部数据
@GetMapping
public String getId(){
System.out.println("spring boot is running..");
System.out.println(environment.getProperty("country"));
System.out.println(environment.getProperty("likes[1]"));
return "spring boot is running ";
}
}
9、读取yaml引用类型属性数据
- 自定义对象封装指定数据
//定义数据模型封装yaml文件中对应的数据
//定义为spring管控的bean
@Component
//指定加载的数据
@ConfigurationProperties(prefix = "datasource")
public class MyDateSource {
private String dirver;
private String url;
private String username;
private String password;
}
#创建类,用于封装下面的数据
#由spring帮我们去加载数据到对象中,一定要告诉spring加载这组信息
#使用时候从spring中直接获取信息使用
datasource:
driver: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:/springboot_db
username: root
password: 123456
springboot整合第三方技术
1、springboot整合JUnit
- 导入测试对应的starter
- 测试类使用@SpringBootTest注解
- 使用自动装配的形式添加要测试的对象
- 测试类如果存在于引导类所在包或子包中无需指定引导类
- 测试类如果不存在于引导类所在的包或子包中,则需要通过classes属性指定引导类
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
//作用:设置JUnit记载的springboot启动类
@SpringBootTest
class Springbootdemo001ApplicationTests {
//注入你要测试的对象
@Autowired
private UserDao userDao;
@Test
void contextLoads() {
//执行要测试的对象对应的方法
userDao.save();
}
}
2、springboot整合Mybatis
- 选择当前模块需要使用的技术集
- 设置数据源参数(数据库连接相关信息转换成配置)
#配置相关信息
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/javacode2020
username: root
password: root
- 定义数据层接口与映射配置(数据库sql映射需要添加@Mapper被容器识别到,用配置文件也可以)
@Mapper
@Repository
public interface BookDao {
@Select("select * from tbl_book where id = #{id}")
public Book getById(Integer id);
}
3、springboot整合mybatisPlus
- 手动添加Springboot整合Mybatis-plus的坐标,可以通过mvnreposotory获取
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.2</version>
</dependency>
- 定义数据层接口与映射配置,继承BaseMapper
@Mapper
@Repository
public interface BookDao extends BaseMapper<Book> {
}
4、整合Druid
- 加入Druid的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
- 修改配置文件
spring:
datasource:
druid:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/javacode2020
username: root
password: root
SSMP整合案例制作分析
1、案例实现方案分析
- 实体类开发—使用lombok快速制作实体类
- Dao开发—整合MybatisPlus,制作数据层测试类
- Servcie开发—基于MybatisPlus进行增量开发,制作业务层测试类
- Controller开发—基于RestFul开发,使用postman测试接口功能
- Controller开发—前后端开发协议制作
- 页面开发—基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理
- 项目异常处理
- 按条件查询—页面功能调整、controller修正功能、service修正功能
2、实体类快速开发(lombok)
- lombok,一个java类库,提供了一组注解,简化pojo实体类开发
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
- 常用注解
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
3、数据层的开发
- 导入MybatisPlus和Druid对应的starter
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.2</version>
</dependency>
- 配置 数据源与MybatisPlus对应的基础配置(id生成策略使用数据库自增策略)
#配置相关信息
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/javacode2020
username: root
password: root
#设置mp的相关配置(表名tbl_book和book类名不一致时)
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto #这个是设置数据库主键自增的,不然mybatis插入数据的时候会用自己的雪花算法自增导致报错
- 继承BaseMapper并指定泛型
@Mapper
@Repository
public interface BookDao extends BaseMapper<Book> {
}
- 为方便调试开启MybatisPlus运行日志
在配置文件中加上日志开启
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto #这个是设置数据库主键自增的,不然mybatis插入数据的时候会用自己的雪花算法自增导致报错
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启MP运行日志
- 分页功能
分页操作需要设定分页对象Page
@Test
void test1(){
IPage page = new Page(1,5);
bookDao.selectPage(page,null);
}
IPage对象中封装了分页操作中的所有数据
—数据
—当前页码值
—每页数据总量
—最大页码值
—数据总量
分页操作是在MybatisPlus的常规操作基础上增强得到,内部是动态的拼写sql语句,因此需要增强对应的功能,使用MybatisPlus拦截器实现
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//定义mp拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加具体的拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
- 条件查询
使用QueryWrapper对象封装查询条件,推荐使用LamdaQueryWrapper对象,所有查询操作封装成方法调用
@Test
void test2(){
QueryWrapper<Book> wrapper = new QueryWrapper();
wrapper.like("name", "java");
//wrapper中有很多条件查询的方法,可以去具体学习
bookDao.selectList(wrapper);
}
@Test
void test3(){
String name = "1";
LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
wrapper.like(name != null ,Book::getName ,name );
bookDao.selectList(wrapper);
}
支持动态拼写查询条件
@Test
void test4(){
//分页条件查询
String name = "java";
IPage page = new Page(1,5);
LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
wrapper.like(Strings.isNotEmpty(name) ,Book::getName ,name );
bookDao.selectPage(page,wrapper);
}
4、业务层标准的开发
接口定义
package com.itheima.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itheima.domain.Book;
import java.util.List;
public interface BookService {
Boolean save(Book book);
Boolean update(Book book);
Boolean delete(Integer id);
Book getById(Integer id);
List<Book> getAll();
IPage<Book> getPage(int currentPage, int pageSize);
}
实现类定义
package com.itheima.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.dao.BookDao;
import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
@Override
public Boolean save(Book book) {
return bookDao.insert(book) > 0;
}
@Override
public Boolean update(Book book) {
return bookDao.updateById(book) > 0;
}
@Override
public Boolean delete(Integer id) {
return bookDao.deleteById(id) > 0;
}
@Override
public Book getById(Integer id) {
return bookDao.selectById(id);
}
@Override
public List<Book> getAll() {
return bookDao.selectList(null);
}
@Override
public IPage<Book> getPage(int currentPage, int pageSize) {
IPage<Book> page = new Page<>(currentPage,pageSize);
return bookDao.selectPage(page,null);
}
}
5、业务层快速开发
使用MybatisPlus提供有业务层通用接口(IService),与业务层通用实现类(ServiceImpl)
在通用类基础上做功能重载或功能追加
注意重载时不要覆盖原始操作,避免原始提供的功能丢失
接口定义
public interface IBookService extends IService<Book> {
}
实现类定义
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
}
6、表现层开发
- 基于restful制作表现层接口
–新增:post,删除:delete,修改:put,查询:get
–接收参数:实体数据:@requestBody、路径变量:@PathVariable
package com.itheima.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itheima.domain.Book;
import com.itheima.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private IBookService bookService;
//查询所有的记录
@GetMapping
public List<Book> getAll(){
return bookService.list();
}
//查询单个记录
@GetMapping("{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById(id);
}
//添加操作
@PostMapping
public Boolean save(@RequestBody Book book){
return bookService.save(book);
}
//修改操作
@PutMapping
public Boolean update(@RequestBody Book book){
return bookService.modify(book);
}
//删除操作
@DeleteMapping("{id}")
public Boolean delete(@PathVariable Integer id){
return bookService.removeById(id);
}
//分页操作
@GetMapping("{currentPage}/{pageSize}")
public IPage<Book> getPage(@PathVariable int currentPage ,@PathVariable int pageSize){
return bookService.getPage(currentPage, pageSize);
}
}
7、表现层消息一致性处理
- 设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议
package com.itheima.util;
import lombok.Data;
@Data
public class Result {
private Boolean flag;
private Object data;
public Result() {
}
public Result(Boolean flag, Object data) {
this.flag = flag;
this.data = data;
}
public Result(Boolean flag) {
this.flag = flag;
}
}
package com.itheima.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itheima.domain.Book;
import com.itheima.service.IBookService;
import com.itheima.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private IBookService bookService;
//查询所有的记录
@GetMapping
public Result getAll(){
return new Result(true,bookService.list());
}
//查询单个记录
@GetMapping("{id}")
public Result getById(@PathVariable Integer id){
return new Result(true,bookService.getById(id));
}
//添加操作
@PostMapping
public Result save(@RequestBody Book book){
return new Result(bookService.save(book));
}
//修改操作
@PutMapping
public Result update(@RequestBody Book book){
return new Result(bookService.modify(book));
}
//删除操作
@DeleteMapping("{id}")
public Result delete(@PathVariable Integer id){
return new Result(bookService.removeById(id));
}
//分页操作
@GetMapping("{currentPage}/{pageSize}")
public Result getPage(@PathVariable int currentPage ,@PathVariable int pageSize){
return new Result(true,bookService.getPage(currentPage, pageSize));
}
}
8、前后端调用(axios发送异步请求)
- 前端发送异步请求,调用后端接口
getAll() {
//发送异步请求
axios.get("/books").then((res)=>{
console.log(res.data);
})
},
单体项目中页面放置在resources/static目录下
created钩子函数用户初始化页面时发起调用
页面使用axios发送异步请求获取数据后确认前后端是否联通
9、列表功能
- 列表页
利用前端数据双向绑定进行数据展示
//列表
getAll() {
//发送异步请求获取全部数据
axios.get("/books").then((res)=>{
this.dataList = res.data.data;
})
},
10、添加功能
请求方式使用post调用后台对应操作
添加操作结束后动态刷新页面加载页面数据
根据操作结果不同,显示对应的提示信息
弹出添加div时清除表单数据
- 弹出添加窗口
//弹出添加窗口
handleCreate() {
this.dialogFormVisible = true;
//重置表单数据,不然新建会有上次输入的值
this.resetForm();
},
- 清除数据
//重置表单
resetForm() {
this.formData = {};
},
- 添加
//添加
handleAdd () {
axios.post("/books",this.formData).then((res)=>{
//如果添加成功
if (res.data.flag){
//1.关闭弹层
this.dialogFormVisible = false;
this.$message.success("添加成功");
}else{
this.$message.error("添加失败");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
},
11、删除功能
- 删除
1.请求方式使用delete调用后台对应操作
2.删除操作需要传递当前行数据对应得id值到后台
3.删除操作结束后动态刷新页面加载数据
4.根据操作结果不同,显示对应得提示信息
5.删除操作前弹出提示框避免操作失误
// 删除
handleDelete(row) {
this.$confirm("确定删除吗?","提示",{type:"info"}).then((res)=>{
axios.delete("/books/"+row.id).then((res)=>{
if (res.data.flag){
this.$message.success("删除成功");
}else{
this.$message.error("删除失败");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
})
}).catch(()=>{
this.$message.info("取消操作");
})
},
12、修改功能
- 弹出修改窗口
1.加载要修改数据通过传递当前行数据对应得id值到后台查询数据
2.利用前端数据双向绑定将查询到得数据进行回显
//弹出编辑窗口
handleUpdate(row) {
axios.get("/books/"+row.id).then((res)=>{
if (res.data.flag && res.data.data != null){
//展示弹层,加载数据
this.formData = res.data.data;
this.dialogFormVisible4Edit = true;
}else{
this.$message.error("数据同步失败,自动刷新");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
})
},
- 修改操作
1.请求方式使用put调用后台对应操作
2.修改操作结束后动态刷新页面加载数据(同新增)
3.根据操作结果不同,显示对应得提示信息
//修改
handleEdit() {
axios.put("/books",this.formData).then((res)=>{
if (res.data.flag){
//1、关闭弹层
this.dialogFormVisible4Edit = false;
this.$message.success("修改成功");
}else{
this.$message.error("修改失败");
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
})
},
13、异常消息处理
- 对异常进行统一处理,出现异常后,返回指定信息
1.使用注解@RestControllerAdvice定义Springmvc异常处理器用来处理异常的
2.异常处理必须被扫描加载,否则无法生效
3.表现层返回结果得模型类中添加消息属性用来传递消息到页面
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class)
public Result doOtherException(Exception e){
e.printStackTrace();
return new Result("系统错误,请稍后再试!");
}
}
- 可以在表现层Controller中进行消息统一处理(Result类)
//添加操作
@PostMapping
public Result save(@RequestBody Book book) throws Exception {
if (book.getName().equals("123")){
throw new Exception();
}
boolean flag = bookService.save(book);
return new Result(flag,flag ? "添加成功":"添加失败");
}
14、分页
- 页面使用el分页组件添加分页功能
<!--分页组件-->
<div class="pagination-container">
<el-pagination
class="pagiantion"
@current-change="handleCurrentChange"
:current-page="pagination.currentPage"
:page-size="pagination.pageSize"
layout="total, prev, pager, next, jumper"
:total="pagination.total">
</el-pagination>
</div>
- 定义分页组件需要使用得数据并将数据绑定到分页组件
pagination: {//分页相关模型数据
currentPage: 1,//当前页码
pageSize:10,//每页显示的记录数
total:0//总记录数
}
- 替换全部查询为分页查询功能
//分页查询
getAll() {
//发送异步请求获取分页数据
axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize).then((res)=>{
this.pagination.currentPage = res.data.data.current;
this.pagination.pageSize = res.data.data.size;
this.pagination.total = res.data.data.total;
this.dataList = res.data.data.records;
})
},
- 分页页码值切换
//切换页码
handleCurrentChange(currentPage) {
//修改页码值为当前选中得页码值
this.pagination.currentPage = currentPage;
//执行查询
this.getAll();
},
- 分页功能维护(删除bug)
对查询结果进行校验,如果当前页码值大于最大页码值,使用最大页码值作为当前页码值重新查询
//分页操作
@GetMapping("/{currentPage}/{pageSize}")
public Result getPage(@PathVariable int currentPage ,@PathVariable int pageSize){
IPage<Book> page = bookService.getPage(currentPage, pageSize);
//如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
if (currentPage > page.getPages()){
page = bookService.getPage((int) page.getPages(), pageSize);
}
return new Result(true,page);
}
15、条件查询
- 查询条件数据封装
1、单独封装
2、与分页操作混合封装
pagination: {//分页相关模型数据
currentPage: 1,//当前页码
pageSize:10,//每页显示的记录数
total:0,//总记录数
name:"",
type: "",
description:""
}
- 页面数据模型绑定(v-model)
<div class="filter-container">
<el-input placeholder="图书类别" v-model="pagination.type" style="width: 200px;" class="filter-item"></el-input>
<el-input placeholder="图书名称" v-model="pagination.name" style="width: 200px;" class="filter-item"></el-input>
<el-input placeholder="图书描述" v-model="pagination.description" style="width: 200px;" class="filter-item"></el-input>
<el-button @click="getAll()" class="dalfBut">查询</el-button>
<el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>
</div>
- 组织数据成为get请求发送得数据
//分页查询
getAll() {
//获取查询条件
param = "?name="+this.pagination.name;
param += "&type="+this.pagination.type;
param += "&description="+this.pagination.description;
//发送异步请求获取分页数据
axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param).then((res)=>{
this.pagination.currentPage = res.data.data.current;
this.pagination.pageSize = res.data.data.size;
this.pagination.total = res.data.data.total;
this.dataList = res.data.data.records;
})
},
- controller接收参数(Book类接收)
//分页操作
@GetMapping("/{currentPage}/{pageSize}")
public Result getPage(@PathVariable int currentPage ,@PathVariable int pageSize,Book book){
IPage<Book> page = bookService.getPage(currentPage, pageSize,book);
//如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
if (currentPage > page.getPages()){
page = bookService.getPage((int) page.getPages(), pageSize,book);
}
return new Result(true,page);
}
- 业务层接口功能开发
@Override
public IPage getPage(int currentPage, int pageSize, Book book) {
IPage page = new Page(currentPage,pageSize);
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
//组织条件
lqw.like(Strings.isNotEmpty(book.getName()), Book::getName,book.getName());
lqw.like(Strings.isNotEmpty(book.getType()), Book::getType,book.getType());
lqw.like(Strings.isNotEmpty(book.getDescription()), Book::getDescription,book.getDescription());
return bookDao.selectPage(page, lqw);
}