学习:SSMP整合综合案例(2025
创建项目
导入starter
新建查询
(Maven的setting
如果您不确定 Maven 安装在哪里,可以通过以下方式查找:在 Windows 上:打开命令提示符
输入 mvn -version 命令
查看输出中的 "Maven home:" 信息
或者在创建项目时
pom.xml
<?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><groupId>com.example</groupId><artifactId>springboot_ssmp</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot_ssmp</name><description>springboot_ssmp</description><properties><java.version>11</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.6.13</spring-boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version> <!-- 使用最新版本 --></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.6</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>11</source><target>11</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.example.springboot_ssmp.SpringbootSsmpApplication</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>
application.yml
# 服务器配置
server:# 设置服务器端口号为80port: 80# Spring框架配置
spring:# 数据源配置datasource:# Druid数据源配置druid:# MySQL驱动类名driver-class-name: com.mysql.cj.jdbc.Driver# 数据库连接URL,指定本地MySQL服务器,端口3306,数据库名为text,使用UTC时区url: jdbc:mysql://localhost:3306/text?serverTimezone=UTC# 数据库用户名username: root# 数据库密码password: 你的密码# MyBatis-Plus框架配置
mybatis-plus:# 全局配置global-config:# 数据库配置db-config:# 表名前缀,所有实体类对应的表名会自动添加此前缀table-prefix: tbl_!# 主键ID生成策略为自增id-type: auto# MyBatis-Plus配置configuration:# 设置SQL日志实现类,将SQL语句输出到控制台log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
根据表结构,制作对应的实体类
public class Book {private Integer id;private String type;private String name;private String description;
}
使用MyBatisPlus的标准通用接口BaseMapper加速开发
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
package dao;import book.Book;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface BookDao extends BaseMapper<Book> {
}
制作测试类测试结果
package com.example.springboot_ssmp;import com.example.springboot_ssmp.book.Book;
import com.example.springboot_ssmp.dao.BookDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.Assert;import java.util.List;@SpringBootTest
public class BookDaoTest {@Autowiredprivate BookDao bookDao;@Testvoid testGetById() {System.out.println(bookDao.selectById(1));}@Testvoid testSave() {Book book = new Book();book.setType("测试数据123");book.setName("测试数据123");book.setDescription("测试数据123");bookDao.insert(book);}@Testvoid testUpdate() {Book book = new Book();book.setId(17);book.setType("测试数据abcdefg");book.setName("测试数据123");book.setDescription("测试数据123");bookDao.updateById(book);}@Testvoid testDelete() {bookDao.deleteById(16);}@Testvoid testGetAll() {bookDao.selectList(null);}}
定义MyBatisPlus拦截器并将其设置为Spring管控的bean
package com.example.springboot_ssmp.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 {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;}
}
业务层接口定义
package com.example.springboot_ssmp.service;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.springboot_ssmp.book.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.example.springboot_ssmp.service.impl;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot_ssmp.book.Book;
import com.example.springboot_ssmp.dao.BookDao;
import com.example.springboot_ssmp.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Overridepublic Boolean save(Book book) {return bookDao.insert(book) > 0;}@Overridepublic Boolean update(Book book) {return bookDao.updateById(book) > 0;}@Overridepublic Boolean delete(Integer id) {return bookDao.deleteById(id) > 0;}@Overridepublic Book getById(Integer id) {return bookDao.selectById(id);}@Overridepublic List<Book> getAll() {return bookDao.selectList(null);}@Overridepublic IPage<Book> getPage(int currentPage, int pageSize) {IPage page = new Page(currentPage, pageSize);bookDao.selectPage(page, null);return page;}
}
对业务层接口进行测试
package com.example.springboot_ssmp;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot_ssmp.book.Book;
import com.example.springboot_ssmp.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 BookServiceTest {@Autowiredprivate BookService bookService;@Testvoid testGetById() {System.out.println(bookService.getById(4));}@Testvoid testSave() {Book book = new Book();book.setType("测试数据123");book.setName("测试数据123");book.setDescription("测试数据123");bookService.save(book);}@Testvoid testUpdate() {Book book = new Book();book.setId(17);book.setType("-----------------");book.setName("测试数据123");book.setDescription("测试数据123");bookService.update(book);}@Testvoid testDelete() {bookService.delete(18);}@Testvoid testGetAll() {bookService.getAll();}@Testvoid testGetPageByParams() {// 定义页码和每页大小int currentPage = 2;int pageSize = 5;// 创建分页对象IPage<Book> page = new Page<>(currentPage, pageSize);// 输出分页信息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. 数据库操作结果
插入操作:
- 成功插入了一条测试数据
- SQL:
INSERT INTO tbl_book (type, name, description) VALUES ('测试数据123', '测试数据123', '测试数据123')
- 结果: 1条记录被插入
查询操作:
- 成功查询了ID为4的图书
- SQL:
SELECT id,type,name,description FROM tbl_book WHERE id=?
- 结果: 找到1条记录
Book(id=4, type=计算机理论, name=Spring MVC+MyBatis开发从入门到项目实战, description=源码级剖析Spring框架,适合已掌握Java基础的读者)
分页查询:
- 执行了分页查询,但结果为空
- 当前页码: 2
- 每页大小: 5
- 总记录数: 0
- 总页数: 0
- 当前页数据: []
删除操作:
- 尝试删除ID为18的图书
- SQL:
DELETE FROM tbl_book WHERE id=?
- 结果: 0条记录被删除(因为ID为18的记录不存在)
更新操作:
- 尝试更新ID为17的图书
- SQL:
UPDATE tbl_book SET type=?, name=?, description=? WHERE id=?
- 结果: 0条记录被更新(因为ID为17的记录不存在)
业务层快速开发
BookService.java
package com.example.springboot_ssmp.service;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.springboot_ssmp.book.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);
//}
//import com.baomidou.mybatisplus.extension.service.IService;public interface BookService extends IService<Book> {boolean saveBook(Book book);boolean modify(Book book);boolean delete(Integer id);IPage<Book> getPage(int currentPage, int pageSize);IPage<Book> getPage(int currentPage,int pageSize,Book book);
}
BookServiceImpl.java
package com.example.springboot_ssmp.service.impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot_ssmp.book.Book;
import com.example.springboot_ssmp.dao.BookDao;
import com.example.springboot_ssmp.service.BookService;
import org.apache.logging.log4j.util.Strings;
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 page = new Page(currentPage, pageSize);
// bookDao.selectPage(page, null);
// return page;
// }
//}@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements BookService {@Autowiredprivate BookDao bookDao;@Overridepublic boolean saveBook(Book book) {return bookDao.insert(book) > 0;}// @Override
// public boolean updata(Book book) {
// return false;
// }@Overridepublic boolean modify(Book book) {return bookDao.updateById(book) > 0;}@Overridepublic boolean delete(Integer id) {return bookDao.deleteById(id) > 0;}@Overridepublic IPage<Book> getPage(int currentPage, int pageSize) {IPage page = new Page(currentPage,pageSize);bookDao.selectPage(page,null);return page;}@Overridepublic IPage<Book> getPage(int currentPage, int pageSize, Book book) {LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();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;}
}
测试
BookServiceTest.java
package com.example.springboot_ssmp;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot_ssmp.book.Book;
import com.example.springboot_ssmp.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 BookServiceTest {@Autowiredprivate BookService bookService;@Testvoid testGetById() {System.out.println(bookService.getById(4));}@Testvoid testSave() {Book book = new Book();book.setType("测试数据123");book.setName("测试数据123");book.setDescription("测试数据123");bookService.save(book);}@Testvoid testUpdate() {Book book = new Book();book.setId(17);book.setType("-----------------");book.setName("测试数据123");book.setDescription("测试数据123");bookService.modify(book);}@Testvoid testDelete() {bookService.delete(18);}// @Test
// void testGetAll() {
// bookService.getAll();
// }@Testvoid testGetPageByParams() {// 定义页码和每页大小int currentPage = 2;int pageSize = 5;// 创建分页对象IPage<Book> page = new Page<>(currentPage, pageSize);// 输出分页信息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());}}
测试结果
查询操作:
- 成功查询了ID为4的图书
- SQL:
SELECT id,type,name,description FROM tbl_book WHERE id=?
- 参数: 4
- 结果: 找到1条记录
Book(id=4, type=计算机理论, name=Spring MVC+MyBatis开发从入门到项目实战, description=源码级剖析Spring框架,适合已掌握Java基础的读者)
分页查询:
- 执行了分页查询,但结果为空
- 当前页码: 2
- 每页大小: 5
- 总记录数: 0
- 总页数: 0
- 当前页数据: []
删除操作:
- 尝试删除ID为18的图书
- SQL:
DELETE FROM tbl_book WHERE id=?
- 参数: 18
- 结果: 0条记录被删除(可能因为ID为18的记录不存在)
表现层开发
package com.example.springboot_ssmp.controller;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.springboot_ssmp.book.Book;
import com.example.springboot_ssmp.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/books")
public class BookController {@Autowiredprivate BookService bookService;@GetMappingpublic List<Book> getAll(){return bookService.list();}@PostMappingpublic Boolean save(@RequestBody Book book){return bookService.save(book);}@PutMappingpublic 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("{currentPage}/{pageSize}")public IPage<Book> getPage(@PathVariable int currentPage, @PathVariable int pageSize){return bookService.getPage(currentPage,pageSize, null);}
}
功能测试通过Apifox工具进行
PUT请求传递json数据,后台实用@RequestBody接收数据
前后端数据协议
R
package com.example.springboot_ssmp.controller.utils;
import lombok.Data;@Data
public class R {private Boolean flag;private Object data;private String msg;public R() {}public R(Boolean flag) {this.flag = flag;}public R(Boolean flag, Object data) {this.flag = flag;this.data = data;}public R(Boolean flag, String msg) {this.flag = flag;this.msg = msg;}public R(String msg) {this.flag = false;this.msg = msg;}
}
BookController.java
package com.example.springboot_ssmp.controller;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.springboot_ssmp.book.Book;
import com.example.springboot_ssmp.controller.utils.R;
import com.example.springboot_ssmp.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.io.IOException;@RestController
@RequestMapping("/books")
public class BookController {@Autowiredprivate BookService bookService;@GetMappingpublic R getAll() {return new R(true, bookService.list());}@PostMappingpublic R save(@RequestBody Book book) throws IOException {if (book.getName().equals("123")) throw new IOException();boolean flag = bookService.save(book);return new R(flag, flag ? "添加成功^_^" : "添加失败-_-!");}@PutMappingpublic R update(@RequestBody Book book) throws IOException {if (book.getName().equals("123")) throw new IOException();boolean flag = bookService.modify(book);return new R(flag, flag ? "修改成功^_^" : "修改失败-_-!");}@DeleteMapping("{id}")public R delete(@PathVariable Integer id) {return new R(bookService.delete(id));}@GetMapping("{id}")public R getById(@PathVariable Integer id) {return new R(true, bookService.getById(id));}@GetMapping("{currentPage}/{pageSize}")public R 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 R(true, page);}
}
对错误的操作数据格式做同样的格式处理
在表现层做统一的异常处理,使用SpringMVC提供的异常处理器做统一的异常处理
ProjectExceptionAdvice
package com.example.springboot_ssmp.controller.utils;import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;//@ControllerAdvice
@RestControllerAdvice
public class ProjectExceptionAdvice {//拦截所有的异常信息@ExceptionHandler(Exception.class)public R doException(Exception ex) {//记录日志//通知运维//通知开发ex.printStackTrace();return new R("服务器故障,请稍后再试!");}
}
跳过前端