• 基于SpringBoot的SSMP整合案例


    在这里插入图片描述

    🍁博客主页:👉不会压弯的小飞侠
    ✨欢迎关注:👉点赞👍收藏⭐留言✒
    ✨系列专栏:SSM框架整合专栏
    ✨如果觉得博主的文章还不错的话,请三连支持一下博主。
    🔥欢迎大佬指正,一起 学习!一起加油!

    在这里插入图片描述


    🍁前言

    🍁实体类

    🔥改进一下实体类

    • @Data 注解
    • 要先引入lombok,lombok 是什么,Lombok是一个Java类库,提供了一组注解,简化PO30实体类开发提高开发效率。
           <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 因为本项目的创建是SpringBoot阿里云版,在创键的过程中选好相应的技术集,所以无需创建Lombok坐标。

    🔥编写实体类Book

    package com.study.domain;
    import lombok.Data;
    @Data
    public class Book {
        private Integer id;
        private String name;
        private String type;
        private String description;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    🍁数据层快速开发

    • BookDao继承BaseMapper,将拥有了BaseMapper中的所有方法,无需编写 mapper.xml 文件,即可获得CRUD功能
    • Mp接口方法
      • 新增:int insert(T t)
      • 删除:int deleteById(Serializable id)
      • 修改:int updateById(T t)
      • id查询:T selectById(Serializable id)
      • 查询全部:List selectList()
      • 分页查询:IPage selectPage( IPage page)
      • 条件查询:Page selectPage(Wrapper querywrapper)
    • 因为项目整合MyBatisPlus(简称MP),基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率。
    • 👉MyBatisPlus详解(可以点击直接查看进行学习)。
    package com.study.dao;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.study.domain.Book;
    import org.apache.ibatis.annotations.*;
    @Mapper
    public interface BookDao extends BaseMapper<Book> {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    🔥测试dao功能

    编写dao层测试类:

    package com.study;
    import com.study.dao.BookDao;
    import com.study.domain.Book;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import java.util.List;
    @SpringBootTest
    class SssmApplicationTests {
        @Autowired
        private BookDao bookDao;
        @Test
        public void select(){
            List<Book> books = bookDao.selectList(null);
            System.out.println(books);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    测试结果:
    在这里插入图片描述
    🔥报错:在测试使用Mybatis-plus查询数据库时报错,报错信息大概意思时在数据库中没有book这张表。

    🔥解决办法:

    • 第一种
      • 把表名改成book
    • 第二种
      • 把实体类表名按照驼峰命名法改成tbBook
    • 第三种
      • 在application.yml里配置一下数据库表前缀

    🔥配置application.yml

    server:
      port: 80
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
        username: root
        password: root
    mybatis-plus:
      global-config:
        db-config:
          table-prefix: tbl_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行测试:查询全部数据成功!

    在这里插入图片描述

    🍁开启MP运行日志

    • 🔥为方便调试可以开启MyBatisPlus的日志

    • 🔥 使用配置方式开启日志,设置日志输出方式为标准输出

    server:
      port: 80
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
        username: root
        password: root
    mybatis-plus:
      global-config:
        db-config:
          table-prefix: tbl_
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    测试:日志开启成功!

    在这里插入图片描述

    🍁分页

    • 🔥分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能,使用MyBatisPlus拦截器实现
    • 在config包中创建MpConfig.java
    package com.study.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 pageInterceptor(){
            //定义MP拦截器
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            //添加具体的拦截器
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
            return interceptor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    🔥分页测试

    • 分页操作需要设定分页对象IPage
     @Test
        void selectPage(){
            IPage page = new Page(2, 4);
            bookDao.selectPage(page, null);
            System.out.println("当前页码"+page.getCurrent());
            System.out.println("每页数据总量"+page.getSize());
            System.out.println("总页数"+page.getPages());
            System.out.println("数据总量"+page.getTotal());
            System.out.println("当前页数据"+page.getRecords());
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • IPage对象中封装了分页操作中的所有数据
      • 数据
      • 当前页码值
      • 每页数据总量
      • 最大页码值
      • 数据总量

    测试结果:

    在这里插入图片描述

    🍁业务层快速开发

    • 快速开发方案

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

    • 定义接口

    package com.study.service;
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.study.domain.Book;
    import org.springframework.transaction.annotation.Transactional;
    @Transactional
    public interface BookService extends IService<Book> {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 🔥使用通用实现类( ServiceImpl)快速开发ServiceImpl
    • 实现类定义
    package com.study.service.impl;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.study.dao.BookDao;
    import com.study.domain.Book;
    import com.study.service.BookService;
    import org.springframework.stereotype.Service;
    @Service
    public class BookServiceImpl extends ServiceImpl<BookDao,Book> implements BookService {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    🔥测试service功能

    package com.study;
    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.study.domain.Book;
    import com.study.service.BookService;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    @SpringBootTest
    public class BookTest {
        @Autowired
        private BookService BookService;
    
        @Test
        void save(){
            Book b=new Book();
            b.setType("文学");
            b.setName("白鹿原");
            b.setDescription("好看");
            BookService.save(b);
        }
        @Test
        void update(){
            Book b=new Book();
            b.setId(15);
            b.setType("文学");
            b.setName("白鹿原");
            b.setDescription("666");
            BookService.updateById(b);
        }
        @Test
        void delete(){
            BookService.removeById(15);
        }
        @Test
        void findById(){
            System.out.println(BookService.getById(1));
        }
        @Test
        void findAll(){
            BookService.list();
        }
        @Test
        void page(){
            IPage<Book> page = new Page<Book>(2,5);
            BookService.page(page);
            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());
    
        }
    }
    
    
    
    • 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

    测试查询全部数据的功能:

    在这里插入图片描述

    🍁表现层数据一致性处理

    • 设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议
    • 使用通用接口(ISerivce)快速开发Service做分页功能比较麻烦,需要自定义方法,只需要修改 BookService,BookServiceImpl,BookController,中的内容其他都不需要动,为了方便理解把code,给删掉,修改Result。

    BookService

    package com.study.service;
    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.study.domain.Book;
    import org.springframework.transaction.annotation.Transactional;
    @Transactional
    public interface BookService extends IService<Book> {
        boolean saveBook(Book book);
    
        boolean modify(Book book);
    
        boolean delete(Integer id);
    
        IPage<Book> getPage(Integer currentPage, Integer pageSize);
    
        IPage<Book> getPage(Integer currentPage, Integer pageSize, Book book);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    BookServiceImpl

    @Service
    public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements BookService {
        @Autowired
        private BookDao bookDao;
    
        @Override
        public boolean saveBook(Book book) {
            return bookDao.insert(book) > 0;
        }
    
        @Override
        public boolean modify(Book book) {
            return bookDao.updateById(book) > 0;
        }
    
        @Override
        public boolean delete(Integer id) {
            return bookDao.deleteById(id) > 0;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    BookController

    
    @RestController
    @RequestMapping("/books")
    public class BookController {
    
        @Autowired
        private BookService bookService;
        @GetMapping
        public Result getAll(){
            return new Result(true, bookService.list());
        }
    
        @PostMapping
        public Result save(@RequestBody Book book)  {
            return new Result( bookService.saveBook(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.delete(id));
        }
    
        @GetMapping("{id}")
        public Result getById(@PathVariable Integer id){
            return new Result(true, bookService.getById(id));
        }
    
    
    • 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

    🔥Postman测试

    • id查询

    在这里插入图片描述

    • 分页

    在这里插入图片描述

    🍁页面开发

    • 页面开发——基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理
    • 列表、新增、修改、删除,异常消息处理,不需要修改
    • 增加分页、查询功能

    🔥列表、新增、修改、删除,异常消息处理,功能就随便测试一个看能不能运行,修改为例:

    • 流浪地球修改为流浪地球666

    在这里插入图片描述

    • 修改成功

    在这里插入图片描述

    🍁分页

    • 页面使用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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 定义分页组件需要使用的数据并将数据绑定到分页组件
    data: {
        pagination: { // 分页相关模型数据
            currentPage: 1, // 当前页码
            pageSize: 5,	// 每页显示的记录数
            total: 0,		// 总记录数
        }
    },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 替换查询全部功能为分页功能
    getAll() {
        axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize).then((res) => {
    
    	});
    },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 分页查询
    • 使用路径参数传递分页数据或封装对象传递数据
    @GetMapping("/{currentPage}/{pageSize}")
        public Result getPage(@PathVariable int currentPage, @PathVariable int pageSize) {
            return new Result(true, bookService.getPage(currentPage, pageSize));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 加载分页数据
              //分页查询
            getAll() {
                // 发送异步请求
                axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize).then((res) => {
                    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;
                });
            },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果:
    在这里插入图片描述

    • 分页页码值切换
    		   //切换页码
                handleCurrentChange(currentPage) {
                //修改页码值为当前选中的页码值
                this.pagination.currentPage = currentPage;
                //执行查询
                this.getAll();
            },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 分页功能维护(删除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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 与分页操作混合封装
    pagination: {//分页相关模型数据
           currentPage: 1,//当前页码
           pageSize: 5,//每页显示的记录数
           total: 0,//总记录数
           type: "",
           name: "",
           description: ""
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 页面数据模型绑定
    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 组织数据成为get请求发送的数据
    //分页查询
                getAll() {
                    // 组织参数,拼接url请求地址
                    param = "?type=" + this.pagination.type;
                    param += "&name=" + this.pagination.name;
                    param += "&description=" + this.pagination.description;
                    // console.log(param);
    
                    // 发送异步请求
                    axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize + param).then((res) => {
                        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;
                    });
                },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 条件参数组织可以通过条件判定书写的更简洁
    • Controller接收参数进行测试
    @GetMapping("/{currentPage}/{pageSize}")
    public Result getPage(@PathVariable int currentPage, @PathVariable int pageSize, Book book) {
    			System.out.println("参数====>" + book);
        IPage<Book> page = bookService.getPage(currentPage, pageSize);
        // 如果当前页码值大于总页码值,那么重新执行查询操作时,使用最大页码值作为当前页码值
        if (currentPage > page.getPages()) {
            page = bookService.getPage((int) page.getPages(), pageSize);
        }
        return new Result(true, page);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行测试:
    在这里插入图片描述

    • 业务层接口功能开发
      // 分页的条件查询
       IPage<Book> getPage(int currentPage, int pageSize, Book book);
    
    • 1
    • 业务层接口实现类功能开发
    @Override
    public IPage<Book> getPage(int currentPage, int pageSize, Book book) {
        LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper();
        lqw.like(Strings.isNotEmpty(book.getType()), Book::getType, book.getType());
        lqw.like(Strings.isNotEmpty(book.getName()), Book::getName, book.getName());
        lqw.like(Strings.isNotEmpty(book.getDescription()), Book::getDescription, book.getDescription());
        IPage page = new Page(currentPage, pageSize);
        bookDao.selectPage(page, lqw);
        return page;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • Controller调用业务层分页条件查询接口
    @GetMapping("/{currentPage}/{pageSize}")
        public R getPage(@PathVariable int currentPage, @PathVariable int pageSize, Book book) {
    //        System.out.println("参数====>" + book);
            IPage<Book> page = bookService.getPage(currentPage, pageSize, book);
            // 如果当前页码值大于总页码值,那么重新执行查询操作时,使用最大页码值作为当前页码值
            if (currentPage > page.getPages()) {
                page = bookService.getPage((int) page.getPages(), pageSize, book);
            }
            return new R(true, page);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行测试:

    • 搜索搞笑类别的书

    在这里插入图片描述

  • 相关阅读:
    SpringMVC源码解析
    Python 工匠:一个关于模块的小故事
    比例夹管阀及其高精度压力和流量控制解决方案
    vscode 资源管理器移动到右边
    解决Python执行命令时路径空格引发的困扰
    Linux文本处理工具awk用法总结
    从安装python到使用opencv进行人脸检测
    Django框架简单搭建增删改查页面 Django请求生命周期流程图
    clumsy 0.3 发布,十年前推出的差网络环境模拟工具
    DPC15 国产带有 SPI 接口的独立 CAN 控制器兼容替代MCP2551
  • 原文地址:https://blog.csdn.net/qq_43514330/article/details/126008697