基于SpringBoot的SSMP的整合案例

news2025/3/1 8:38:55

基于SpringBoot的SSMP的整合案例

    • 简单介绍
    • 模块创建
    • 创建实体类
    • 导入Mybatis-plus和druid的配置文件
    • 使用junit测试查询方法
    • MP分页查询
    • 按照条件进行查询
    • 业务层Service开发
    • 业务层Service快速开发
    • 表现层开发
    • 表现层 实现分页查询
    • 表现层消息一致性的处理
    • 查询所有书本信息
    • 添加书本
    • 删除操作
    • 修改功能
    • 异常处理功能
    • 添加分页查询

简单介绍

在这里插入图片描述

模块创建

添加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分页组件
  • 定义分页组件绑定的数据模型
  • 异步调用获取分页数据
  • 分页数据页面回显

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/557157.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TensorFlow巨浪中的巨人:大数据领域的引领者 TensorFlow实战【上进小菜猪大数据系列】

上进小菜猪&#xff0c;沈工大软件工程专业&#xff0c;爱好敲代码&#xff0c;持续输出干货。欢迎订阅本专栏&#xff01; 大数据时代的到来带来了海量数据的处理和分析需求。在这个背景下&#xff0c;TensorFlow作为一种强大的深度学习框架&#xff0c;展现了其在大数据领域…

fastreport使用教程(fastreport报表编辑器)

除了库本身&#xff0c;FastReport.Net还包括单独的程序 – Designer和Viewer。 如您所知&#xff0c;第一个用于创建和编辑报表模板。它具有报表预览模式&#xff0c;您可以从中查看报表&#xff0c;将其导出为所需的数据格式并将其发送到打印。 Viewer用于以fpx预览格式查看报…

清华p-tuning | GPT也能做NLU?清华推出p-tuning方法解决GPT系列模型fine-tuning效果比BERT差问题

一、概述 title&#xff1a;GPT Understands, Too 论文地址&#xff1a;https://arxiv.org/abs/2103.10385 代码&#xff1a;https://github.com/THUDM/P-tuning 1.1 Motivation GPTs模型利用传统的fine-tuning技术在NLU任务上效果比较差&#xff0c;比同等量级的BERT效果…

2023/5/22总结

继承 继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法&#xff0c;还可以在子类中重新定义&#xff0c;追加属性和方法。 如图&#xff1a; 在上面的图片中&#xff0c;dog和cat都继承了Animal类&#xff0c;所以dog和cat都可以称为Animal的子类或者派生类&…

chatgpt赋能Python-python_dng

Python DNG&#xff1a;开启更高效的数据处理之路 什么是Python DNG&#xff1f; Python DNG&#xff08;Data NumPy Generator&#xff09;是一种基于Python的高效数据生成器&#xff0c;可以加速数据处理和分析的过程。它基于Numpy数组操作和并行计算思想&#xff0c;可以快…

C++详解NOI题:[NOIP2021] 报数

文章目录 前言一、题目二、暴力解题步骤&#xff08;50分&#xff09;三、打表防坑解题&#xff08;100分&#xff09;总结 前言 受不了CSDN每日一练的在线竞赛系统了&#xff0c;bug多就算了&#xff0c;勉强能用&#xff0c;可那些题目的神描述&#xff0c;到处是错。所以找…

前端面试知识点总结

前言&#xff1a; 博主突击两个月八股拿到美团&#xff08;基础研发&#xff09;&#xff0c;腾讯&#xff08;IEG&#xff09;&#xff0c;百度&#xff08;搜索部门&#xff09;暑期实习offer call&#xff0c;这是我学习过程中整理的前端知识点&#xff0c;内容有些多&#…

【13900k】i9 核显升级驱动

这里写自定义目录标题 官方的助手不能用显卡控制中心提示最新的更新搜索显卡 intel uhd graphics 770 手动下载安装自定义音频为啥也要卸载&#xff1f;新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片…

网络编程——嵌入式(驱动)软开基础(六)

1、简述TCP三次握手的过程。 (1)第一次握手:客户端创建传输控制块,然后向服务器发出连接请求报文(将标志位SYN置1,随机产生一个序列号seq=x),接着进入SYN-SENT状态。 (2)第二次握手:服务器收到请求报文后由SYN=1得到客户端请求建立连接,回复一个确认报文(将标志…

进程启动后到加载Activity的流程源码解析(基于安卓版本28)

文章目录 源码解析总体时序图关键类解析ActivityThreadApplicationThreadInstrumentationClientTransactionActivityStackSupervisorActivityRecord梳理概述源码流程梳理 源码解析 总体时序图 关键类解析 只针对流程中用到的关键类进行解析。 ActivityThread 注意其父类是&…

ES6升级之路:探究模板字符串、startsWith()方法和endsWith()方法、repeat()等新特性。

模版字符串 ES6新增的创建字符串的方式,使用反引号定义 示例 <script>// 1.模板字符串可以解析变量 ${}显示变量的值let name 张三;let sayHello HEllo,我的名字叫${name};console.log(name);console.log(sayHello);let result {name: "zhangsan",age: 20…

Java【TCP 协议2】确认应答、超时重传机制

文章目录 前言一、确认应答1, 什么是确认应答2, 序列号和确认应答号 二、超时重传1, 什么是超时重传 总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系…

python基础(循环语句 while循环、break、continue,字符格式化,运算符)

1. while循环 【1】语法&#xff1a; while 条件:.........举例&#xff1a; print("123") while 条件:......... print(456)【2】循环语句的基本使用 示例1&#xff1a; print("开始") while True:print("hello world") print("结束&…

约瑟夫问题的环形链表实现[Java]

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐如果觉得文章写的不错&#xff0c;欢迎点个关注一键三连&#x1f609;有写的不好的地方也欢迎指正&#xff0c;一同进步&#x1f601;…

(全网最详细攻略)【Crypto++】在Visual studio2022中运行Cryptopp

文章目录 前言一、Cryptopp是什么&#xff1f;1. Cryptopp&#xff08;CRYPTO&#xff09;官方文档wiki 二、下载Cryptopp2. Crypto下载地址3. 下载PEM包 三、在VS2022中使用Cryptopp库4. 处理crypto源文件5. 在VS2022项目中使用crypto库 四、运行代码后一些关于c的错误总结 前…

单片机--中断实验练习

【1】实验要求&#xff1a; STM32上电LED&#xff08;PB0&#xff09;灯亮 &#xff0c;当检测到按键&#xff08;PA8&#xff09;按下时处理中断事件&#xff0c;变量i 扩展&#xff1a;知识点 响应优先级->在两个中断同时触发时&#xff0c;且这两个中断的优先级相同&a…

SpringBootWeb入门

1. SpringBootWeb快速入门 1.1 需求 需求&#xff1a;基于SpringBoot的方式开发一个web应用&#xff0c;浏览器发起请求/hello后&#xff0c;给浏览器返回字符串 “Hello World ~”。 1.2 开发步骤 第1步&#xff1a;创建SpringBoot工程项目 第2步&#xff1a;定义HelloCon…

chatgpt赋能Python-python_docx_目录

简介 Python是一种非常优秀的编程语言&#xff0c;主要用于数据分析、机器学习、人工智能等领域。在这些领域中&#xff0c;常常需要使用文档处理相关的工具&#xff0c;例如Microsoft Word。在使用Python编程的过程中&#xff0c;文档处理是非常常见的操作&#xff0c;因此Py…

AC规则-1

本文主要参考规范 GPD_Secure Element Access Control_vxxx.pdf OMA 架构 基本定义 GP(GlobalPlatform)定义了一套允许各应用提供方独立且安全地管理其在SE上的应用的安全框架&#xff0c;而AC(Access Control)&#xff0c;顾名思义&#xff0c;是对外部应用进行SE上应用访问…

pyinstaller 打包 ! pyinstaller 打包路径问题!wordcloud打包缺失stopwords文件

wordcloud打包缺失stopwords文件 错误描述 Unhandled exception in script Failed to execute scriptmain due to unhandled exception: (Errno 2] No such file or directory: C:\Users\VADMINI\appDatallLocal\Templ\2\ME186322\wordcloud\stopwords解决办法 找到安装word…