您现在的位置是:首页 >学无止境 >基于SpringBoot的SSMP的整合案例网站首页学无止境
基于SpringBoot的SSMP的整合案例
简介基于SpringBoot的SSMP的整合案例
基于SpringBoot的SSMP的整合案例
简单介绍
模块创建
添加spring WEB 和MYSQL driver的依赖
然后手动添加Mybatis-plus和druid的依赖
改写配置文件端口
创建实体类
在domain包下面创建Book类,使用lombook技术自动配置相关get set操作
Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发
添加lombok依赖,不需要添加坐标,因为parent已经包含坐标
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
使用@Data注解简化开发
package com.ustc.domain;
import lombok.Data;
@Data
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
导入Mybatis-plus和druid的配置文件
server:
port: 80
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/da?serverTimezone=UTC
username: root
password: 123456
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
# 配置druid
使用junit测试查询方法
package com.ustc;
import com.ustc.Dao.BookDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.ustc.domain.Book;
@SpringBootTest
class Sp11ApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
System.out.println(bookDao.selectById(1));
}
// 插入操作
@Test
void testSave(){
Book book = new Book();
book.setId(10);
book.setType("心理");
book.setName("111111111111111111");
book.setDescription("dshf");
bookDao.insert(book);
}
// 更新操作
@Test
void testSave1(){
Book book = new Book();
book.setId(10);
book.setType("心理");
book.setName("如何成为富婆");
book.setDescription("dshf");
bookDao.updateById(book);
}
// 删除操作
@Test
void testdelete(){
bookDao.deleteById(1);
}
// 查询全部操作
@Test
void testGetAll(){
System.out.println(bookDao.selectList(null));
}
}
MP分页查询
- 创建分页对象Page
- 创建分页拦截器
// 分页查询操作 需要在配置类中添加拦截器
@Test
void testGetPage(){
IPage page = new Page(1,2);//page是IPage的实现类
// 输出数据
System.out.println(bookDao.selectPage(page,null).getRecords());
}
package com.ustc.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MPConfig {
// 定义拦截器
// 注入拦截器资源
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
// 创建mP拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());// 添加分页拦截器
return interceptor;
}
}
按照条件进行查询
使用QueryWrapper对象封装查询条件,推荐使用LambdaQueryWrapper对象,所有查询操作封装成方法调用
@Test
void testGetBy(){
QueryWrapper<Book> qw = new QueryWrapper<>();
// 设置查询条件
qw.like("name","Spring");
bookDao.selectList(qw);// 传入查询条件
}
@Test
void testGetBy1(){
LambdaQueryWrapper<Book> qw = new LambdaQueryWrapper<>();
// 设置查询条件
qw.like(Book::getName,"Spring");
bookDao.selectList(qw);// 传入查询条件
}
业务层Service开发
Service层接口定义与数据层接口定义具有较大的区别,不要混用
-
selectByUserNameAndPassword(String username,String password) 数据层
-
login(String username,String password) 业务层
-
定义 service接口
package com.ustc.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ustc.domain.Book;
import org.springframework.stereotype.Service;
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);
}
- 定义service接口的实现类
package com.ustc.service.Impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ustc.Dao.BookDao;
import com.ustc.domain.Book;
import com.ustc.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
// 将该实现类定义成业务层的一个bean资源
@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 page = new Page(currentPage,pageSize);
return bookDao.selectPage(page,null);
}
}
- 注入bookService接口资源 进行查询测试
// 分页查询
@Test
void testGetPage1(){
IPage<Book> page = bookService.getPage(1,5);
System.out.println(page.getRecords());
}
// 使用业务层进行查询
@Test
void test1(){
System.out.println(bookService.getById(4));
}
业务层Service快速开发
- 首先定义一个IBookService
package com.ustc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ustc.domain.Book;
public interface IBookService extends IService<Book> {
}
- 实现IBookService接口
package com.ustc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ustc.domain.Book;
import org.springframework.stereotype.Service;
// 记得将实现类 注入为bean资源
@Service
public interface IBookService extends IService<Book> {
}
- 使用通用接口(IService) 快速开发Service
- 使用通用实现类(ServiceImpl<M,T>) 快速开发ServiceImpl
- 可以在通用接口的基础上做功能重载或者功能追加
- 注意重载时不要覆盖原始的操作,避免原始提供的功能丢失
表现层开发
package com.ustc.Controller;
import com.ustc.domain.Book;
import com.ustc.service.IBookService;
import org.apache.ibatis.annotations.Delete;
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("/search")
public List<Book> getAll(){
return bookService.list();
}
// 插入数据 这里的参数 通过请求体传输json数据 添加RequestBody注解
@PostMapping("/insert")
public Boolean save(@RequestBody Book book){
return bookService.save(book);
}
// 修改数据
@PutMapping("/update")
public Boolean update(@RequestBody Book book){
return bookService.modify(book);
}
// 删除数据
@DeleteMapping("/delete/{id}")
public Boolean delete(@PathVariable Integer id){
return bookService.delete(id);
}
// 根据id进行查询 使用pathVariable注解 使得url参数 赋值到形参
@GetMapping("{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById(id);
}
}
使用postman做测试
表现层 实现分页查询
- Controller
@GetMapping("/page/{currentPage}/{pageSize}")
public IPage<Book> getPage(@PathVariable int currentPage,@PathVariable int pageSize){
return bookService.getPage(currentPage,pageSize);
}
- Service
@Override
public IPage<Book> getPage(int currentPage, int pageSize) {
IPage page = new Page(currentPage,pageSize);
bookDao.selectPage(page,null);
return page;
}
表现层消息一致性的处理
设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也成为前后端数据协议
首先定义一个R类,这里的flag表示后端的操作有没有成功,data表示后端传输的数据
package com.ustc.Controller.utils;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.ustc.domain.Book;
import lombok.Data;
@Data
public class R {
private Boolean flag;
private Object data;
public R(){}
public R(Boolean flag){
this.flag = flag;
}
// 构造函数重载
public R(Boolean flag,Object data){
this.flag = flag;
this.data = data;
}
}
之后改写Controller的接口方法,插入,修改,删除操作只需要传入Boolean参数即可,对于需要返回数据的接口,使用另一种构造方法
package com.ustc.Controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ustc.Controller.utils.R;
import com.ustc.domain.Book;
import com.ustc.service.IBookService;
import org.apache.ibatis.annotations.Delete;
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("/search")
public R getAll(){
return new R(true,bookService.list());
}
// 插入数据 这里的参数 通过请求体传输json数据 添加RequestBody注解
@PostMapping("/insert")
public R save(@RequestBody Book book){
return new R(bookService.save(book));
}
// 修改数据
@PutMapping("/update")
public R update(@RequestBody Book book){
// return bookService.modify(book);
return new R(bookService.modify(book));
}
// 删除数据
@DeleteMapping("/delete/{id}")
public R delete(@PathVariable Integer id){
return new R(bookService.delete(id));
}
// 根据id进行查询 使用pathVariable注解 使得url参数 赋值到形参
@GetMapping("{id}")
public R getById(@PathVariable Integer id){
// 第一个参数是flag 第二个参数是 object对象 data
R r = new R(true,bookService.getById(id));
return r;
}
// 分页查询操作
@GetMapping("/page/{currentPage}/{pageSize}")
public R getPage(@PathVariable int currentPage,@PathVariable int pageSize){
return new R(true,bookService.getPage(currentPage,pageSize));
}
}
意义:
- 设计统一的返回值结果类型便于前端开发读取数据
- 返回值结果类型可以根据需求自行设定,没有固定的格式
- 返回值结果类型用于后端和前端进行数据格式统一,也称之为前后端数据协议
查询所有书本信息
发送异步请求,将请求后端查询的数据传给前端,前端数据双向绑定进行数据展示
添加书本
使用axios请求将前端的请求包括数据发送给后端
- 请求方式使用POST调用后台对应操作
- 添加操作结束之后动态刷新页面加载数据
- 根据操作结果不同,显示对应的提示信息
- 弹出添加div时清除表单数据
handleAdd () {
// 使用axios 将数据发送给后端 post请求 发送请求 返回res 检查flag操作是否成功
axios.post("/books",this.formData).then((res)=>{
// 判断当前操作是否成功
if(res.data.flag){
// 关闭弹层
// 点击确定 发送数据之后 关闭弹窗
this.dialogFormVisible = false;
this.$message.success("添加成功");
}else{
this.$message.error("添加失败");
}
}).finally(()=>{
// 重新加载数据
this.getAll();
});
},
删除操作
- 请求方式使用Delete调用后台对应操作
- 删除操作需要传递当前行数据对应的id值到后台
- 删除操作结束之后动态刷新页面加载数据
- 根据操作结果的不同,显示对应的提示信息
- 删除操作前弹出提示框避免误操作
// 删除
handleDelete(row) {
// axios发送异步请求 使用deleteMapping 参数是id 删除操作
this.$confirm("此操作永久删除当前信息,是否继续?","提示",{type:"info"}).then(()=>{
axios.delete("/books/"+row.id).then((res)=>{
if(res.data.flag){
this.$message.success("删除成功");
}else{
this.$message.error("删除失败");
}
}).finally(()=>{
// 不管删除成功 还是失败 都会刷新页面
this.getAll();
});
}).catch(()=>{
this.$message.info("取消操作");
});
},
修改功能
- 加载要修改数据通过传递当前行数据对应的id值到后台查询数据
- 利用前端数据双向绑定将查询到的数据进行回显
- 首先点击编辑按钮 根据id加载后端的数据
- 然后编辑数据,传给后端
//弹出编辑窗口 点击编辑按钮 根据id加载后台的数据
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("数据同步失败 ,自动刷新");
}
}).finally(()=>{
// 重新加载数据 也就是刷新页面
this.getAll();
});
},
//编辑按钮:这个按钮的作用就是根据id查询数据信息 然后填充到页面即可 put操作将表单修改的数据进行回显
handleEdit() {
axios.put("/books",this.formData).then((res)=>{
// 判断当前操作是否成功
if(res.data.flag){
// 关闭弹窗
this.dialogFormVisible4Edit = false;
this.$message.success("添加成功");
}else{
this.$message.error("添加失败");
}
});
},
异常处理功能
自定义异常
package com.itheima.controller.utils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//作为springmvc的异常处理器
//@ControllerAdvice
@RestControllerAdvice
public class ProjectExceptionAdvice {
//拦截所有的异常信息
@ExceptionHandler(Exception.class)
public R doException(Exception ex){
//记录日志
//通知运维
//通知开发
ex.printStackTrace();
return new R("服务器故障,请稍后再试!");
}
}
- 使用注解@RestControllerAdvice定义SpringMVC异常处理器来处理异常
- 异常处理器必须被扫描加载,否则无法生效
- 表现层返回结果的模型类中添加消息属性用来传递消息到页面
添加分页查询
发起请求调用,将当前页码之和每页的展示数据量 传到后端进行查询
getAll() {
//发送异步请求
axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize).then((res)=>{
// console.log(res.data);
this.pagination.pageSize = res.data.data.size;
this.pagination.currentPage = res.data.data.current;
this.pagination.total = res.data.data.total;
// 将请求后端发送的数据传给前端 展示
this.dataList = res.data.data.records;
});
},
- 使用el分页组件
- 定义分页组件绑定的数据模型
- 异步调用获取分页数据
- 分页数据页面回显
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。