Spring Boot + MyBatis-Plus 的现代开发模式

之前的Maven项目和本次需要的环境配置并不一样

之前使用的是:

  • 传统的 MyBatis 框架(非 Spring Boot 环境)

  • 手动管理 SqlSession

  • 使用了 .xml 的 Mapper 映射文件

  • 没有 Spring 容器管理(没有 @Service / @RestController 等)

  • 没有看到分页插件配置,也没有 REST 接口入口

项目结构对比你现在的项目实验要求的项目
框架风格手动搭建的原生 MyBatisSpring Boot 自动化集成
Mapper 类型接口 + XML接口继承 BaseMapper(少量或无 XML)
SqlSession手动获取和关闭Spring 管理,自动注入 Mapper
事务控制手动 commit使用 Spring 的 @Transactional 管理
分页插件没有集成插件要集成 MyBatis-Plus 分页插件
接口风格控制台输出使用 @RestController 提供 REST API
调试方式控制台 + main 方法测试使用 Postman 测试 API 接口

添加 依赖项

依赖名称作用
Spring Web用来写 REST API 接口,也就是你要用 Postman 调的接口
MyBatis Plus是 MyBatis 的增强版,提供了分页插件、条件构造器、简化 DAO 写法
MySQL Driver数据库驱动,让 Java 项目能连接你本地的 MySQL 数据库
Lombok简化实体类写法,比如 @Data 自动生成 getter/setter,不用手写

MyBatis Plus会发现并没有找到

可能用的是 国内 Spring Initializr 镜像站(start.spring.io 国内版),它没集成 MyBatis-Plus 官方模块。这时我们用手动方式加上去就行:

✅ 添加 MyBatis-Plus 的方式

完成创建项目后,在 pom.xml 中手动添加以下依赖:

<!-- MyBatis-Plus 核心依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>
添加后点击 IDEA 右上角的 Maven 小象图标 → Reimport,让它下载依赖。

先MySQL中建立数据库

CREATE DATABASE product_db DEFAULT CHARACTER SET utf8mb4;USE product_db;CREATE TABLE product (id BIGINT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100) NOT NULL,category_level1 VARCHAR(50),category_level2 VARCHAR(50),category_level3 VARCHAR(50),brand VARCHAR(50),price DECIMAL(10, 2)
);

配置 application.properties

spring.application.name=product-service
#这个是 Spring Boot 给你的服务起个名字,比如后续你如果集成了日志系统、监控平台、微服务等,它就能显示“是谁”在运行。
#❗ 这个对本地调试没影响,可以留着,也可以删,不影响实验内容。

设置端口号

server.port=8080
表示你的服务启动后监听 http://localhost:8080,是 Postman 访问接口的基础。

数据库连接配置

spring.datasource.url=jdbc:mysql://localhost:3306/product_db?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

MyBatis-Plus 设置

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
让你在控制台中看到执行的 SQL,非常适合调试查询条件对不对。

spring.application.name=product-serviceserver.port=8080spring.datasource.url=jdbc:mysql://localhost:3306/product_db?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Drivermybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

最后点击运行ProductServiceApplication.java----自动结束,运行失败

这个问题需要先处理一下------

-----------------------------------------------------------------------------------------全局搜索是Ctrl+Shift+N--

原因是mybatis的版本问题,换到3.5.5就不会出现这个bean的问题了

Started ProductServiceApplication in 1.199 seconds (process running for 1.539)Application availability state ReadinessState changed to ACCEPTING_TRAFFIC

🧩 接下来要做的事(建议顺序)

🔧 第 1 步:实体类

  • Product.java → 映射数据库表字段

(便于 MyBatis-Plus 自动匹配)

  • 保持 Java 字段名和数据库字段名一致

  • 如果不一致就用 @TableField@TableId 明确指定

package org.example.productservice.entity;import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;import java.math.BigDecimal;@Data
@TableName("product")
public class Product {@TableId("id")private Long id;@TableField("name")private String name;@TableField("category_level1")private String categoryLevel1;@TableField("category_level2")private String categoryLevel2;@TableField("category_level3")private String categoryLevel3;@TableField("brand")private String brand;@TableField("price")private BigDecimal price;
}

配套说明:

  • @TableName("product"):绑定对应的表名

  • @TableField("xxx"):将 Java 命名风格(驼峰)映射到数据库的下划线字段

  • @TableId("id"):指定主键列

  • BigDecimal:更适合处理 DECIMAL(10, 2) 类型,避免精度丢失

🔧 第 2 步:Mapper 接口

  • ProductMapper.java → 使用 BaseMapper<Product>

package org.example.productservice.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.productservice.entity.Product;@Mapper
public interface ProductMapper extends BaseMapper<Product> {
}
  • extends BaseMapper<Product>
    → 让你继承了 MyBatis-Plus 提供的所有基础增删改查方法(包括分页、条件构造器)

  • @Mapper
    → 是 MyBatis 要求的注解,告诉 Spring 它是一个 Mapper 接口

  • 不需要自己写 XML 映射文件了,MyBatis-Plus 自动帮你做了映射!

🔧 第 3 步:Service 层

  • IProductService.java(接口)

package org.example.productservice.service;import com.baomidou.mybatisplus.extension.service.IService;
import org.example.productservice.entity.Product;public interface IProductService extends IService<Product> {
}
  • ProductServiceImpl.java(实现)

package org.example.productservice.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.productservice.entity.Product;
import org.example.productservice.mapper.ProductMapper;
import org.example.productservice.service.IProductService;
import org.springframework.stereotype.Service;@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
}

原理说明:

  • IService<Product> 接口:

    提供了更高层级的封装,比如 getByIdsaveremoveById 等,默认自带 CRUD

  • ServiceImpl<Mapper, Entity> 实现类:

    自动帮你实现这些方法,不用自己写 SQL

-----------------

后端结构已经扎实完整,马上就能提供接口服务了。

🔧 第 4 步:Controller 层

📁 路径:org.example.productservice.controller

package org.example.productservice.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.example.productservice.entity.Product;
import org.example.productservice.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/products")
public class ProductController {@Autowiredprivate IProductService productService;@GetMapping("/page")public Page<Product> getProductPage(@RequestParam(defaultValue = "1") int page,@RequestParam(defaultValue = "10") int size,@RequestParam(required = false) String name) {QueryWrapper<Product> queryWrapper = new QueryWrapper<>();if (name != null && !name.isEmpty()) {queryWrapper.like("name", name);}return productService.page(new Page<>(page, size), queryWrapper);}
}

🔧 第 5 步:分页插件配置

📁 创建一个配置类:MyBatisPlusConfig.java
路径:org.example.productservice.config

package org.example.productservice.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 MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor paginationInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;}
}

----

此时先暂时尝试运行项目在idea中

现在虽然逻辑没写很多,但只靠你目前写的代码:

你已经拥有了分页、条件查询、自动封装结果、返回 JSON 的完整功能

运行后报错

Spring Boot 升级 3.2 报错 Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String_invalid value type for attribute 'factorybeanobjec-CSDN博客

需要注意下 Maven 的坐标标识 是mybatis-plus-spring-boot3-starter,这点和SpringBoot 2 的依赖坐标mybatis-plus-boot-starter有所区别。

对于

创建商品处理的业务接口实现类 ProductServiceImpl,完成按商品名称、多级类别、品牌查询商品

MyBatis-Plus 自带的是“基础查询”,但你要做复杂查询逻辑(多条件),就得:

  • 自己在 Controller 里组合 QueryWrapper

  • 或者把逻辑抽出来写在 ServiceImpl 中(推荐,逻辑更清晰)

总结你现在做的是:

  • ✅ REST 风格接口设计

  • ✅ SpringBoot + MyBatisPlus 的现代开发方式

  • ✅ 使用分层架构(Controller + ServiceImpl + Mapper + Entity)

所以你这叫遵循 REST 风格的分层 Web API 实现,并且是目前企业开发里非常标准的一种写法。

先暂时用游览器的url直接访问

postman暂时还是不方便

records 数组中是空对象 {},说明实体类字段没被序列化。

接口逻辑是对的,返回结构也有 total 等字段,说明查询成功。但 records 是空对象 {}

✅ 最可能原因:

你的 Product 实体类字段没有加上 getter/setterLombok 注解 @Data,导致无法被 Jackson 序列化为 JSON。

期望结果
{"records": [{"id": 1,"name": "小米电视 4C","categoryLevel1": "家电","categoryLevel2": "电视","categoryLevel3": "智能电视","brand": "小米","price": 2299.00},{"id": 2,"name": "海信电视 H55","categoryLevel1": "家电","categoryLevel2": "电视","categoryLevel3": "液晶电视","brand": "海信","price": 2699.00}],"total": 2,"size": 10,"current": 1,"pages": 1
}

total, size, current, pages 是分页系统生成的,是 Page<Product> 本身的结构。

🔄 IService 提供的是分页机制

Page<Product> page = productService.page(new Page<>(page, size), queryWrapper);

的确是lombok的问题,全部手动设置构造函数就解决了

“按商品名称、多级类别、品牌查询商品”的业务逻辑

需要修改的类是:ProductServiceImplProductController

QueryWrapper<Product> 是 MyBatis-Plus 提供的条件构造器,用来拼接 SQL 查询语句。

wrapper.like("name", name) 是模糊查询(SQL 中的 LIKE '%关键词%')。

wrapper.eq(...) 是精确匹配(SQL 中的 = 值)。

this.page(...) 调用 MyBatis-Plus 提供的分页查询方法(自动生成 limit offset 分页语句)。

👉 为什么写在 ProductServiceImpl

因为 Service 是 业务逻辑层,用于组织和处理“多个条件组合”的查询。控制器不直接处理数据拼接,而是委托给 Service 层。

✅ 二、IProductService:定义接口的契约

目的:明确 ProductService 应该提供哪些方法。

  • 在 Java 中,通过接口来隔离调用者(Controller)与实现者(Impl)。

  • 当 Controller 调用 searchProducts(...),它并不关心方法的具体实现是谁,只要接口定义存在即可。

👉 为什么要定义这个接口?

是为了松耦合:如果将来想换一个查询逻辑,只需更换 Impl 实现,不必改调用方(Controller)。

✅ 三、ProductController:暴露查询接口(给前端或 Postman 测试)

目的:将你定义的查询功能开放为一个 HTTP 请求入口。

  • @GetMapping("/search") 表示它是一个 GET 请求,路径为 /api/products/search

  • @RequestParam 是接收 URL 参数的注解,比如 ?name=电视

  • 调用的是 productService.searchProducts(...),把参数传入,调用你刚实现的业务逻辑。

👉 为什么写在 Controller?

控制器是Web 层的入口,处理请求参数、调用服务、返回数据。它不直接写业务细节,而是只负责“调度”。

Alt + Enter 自动导入

使用你在 ProductServiceImpl 里自定义的 searchProducts 方法对商品进行 条件查询,不用默认的分页方法名 getProductPage

-----------

完成

postman查询(游览器也可以,只不过也是这个更专业一点吧,,目前其实游览器直接输入都可以了)

类名作用
Product实体类,对应数据库字段
ProductMapperMapper接口,继承自 BaseMapper
IProductService服务接口,继承 IService,并声明 searchProducts 方法
ProductServiceImpl服务实现,继承 ServiceImpl,实现自定义搜索逻辑
ProductController控制器,定义 /page/search 两个查询接口

重点接口功能

/api/products/page
  • 基础分页查询,支持按 name 模糊搜索(如:?name=小米

/api/products/search
  • 高级组合条件查询:支持传入 namecategory_level1category_level2category_level3brand

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

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

相关文章

【Quest开发】极简版!透视环境下抠出身体并能遮挡身体上的服装

前两天发了一个很复杂的版本&#xff0c;又鼓捣了一下发现完全没有必要。我之前的理解有点偏&#xff08;不是错误的但用法错了&#xff09;&#xff0c;但是有一些小伙伴收藏了&#xff0c;害怕里面的某些东西对谁有用&#xff0c;所以写了一篇新的&#xff0c;前两步配置环境…

vue 常见ui库对比(element、ant、antV等)

Element UI 1. 简介 Element UI 是一个基于 Vue 2 和 Vue 3 的企业级 UI 组件库&#xff0c;提供了丰富的组件和主题定制功能。官方网站&#xff1a;Element UI 2. 主要特点 丰富的组件&#xff1a;包括表单、表格、布局、导航、弹窗等多种组件。主题定制&#xff1a;支持主…

MATLAB画一把伞

% 伞的参数num_ribs 5; % 伞骨数量修改为5R 1; % 伞的半径height 0.5; % 伞的高度handle_length 2; % 伞柄长度semicircle_radius 0.26; % 伞柄末端半圆的半径% 生成伞叶网格theta linspace(0, 2*pi, 100);phi linspace(0, pi/2, 50);[Theta, Phi] meshgrid(theta, phi…

如何在 Go 中实现各种类型的链表?

链表是动态内存分配中最常见的数据结构之一。它由一组有限的元素组成&#xff0c;每个元素&#xff08;节点&#xff09;至少占用两块内存&#xff1a;一块用于存放数据&#xff0c;另一块用于存放指向下一个节点的指针。本文教程将说明在 Go 语言中如何借助指针和结构体类型来…

新一代机载相控阵雷达的发展

相控阵雷达以其优越的性能在军事领域中有着广阔的应用前景&#xff0c;但由于复杂的技术、昂贵的造价使其应用范围还存在一定的局限性。然而&#xff0c;国内外对相控阵技术的研究非常重视&#xff0c;并取得了丰硕的成果。 军用相控阵雷达主要分为陆基、海基和空基几种类型。 …

多数元素题解(LC:169)

169. 多数元素 核心思想&#xff08;Boyer-Moore 投票算法&#xff09;&#xff1a; 解题思路&#xff1a;可以使用 Boyer-Moore 投票算法、该算法的核心思想是&#xff1a; 维护一个候选元素和计数器、初始时计数器为 0。 遍历数组&#xff1a; 当计数器为 0 时、设置当前元…

数据库 AI 助手测评:Chat2DB、SQLFlow 等工具如何提升开发效率?

一、引言:数据库开发的 “效率革命” 正在发生 在某互联网金融公司的凌晨故障现场,资深 DBA 正满头大汗地排查一条执行超时的 SQL—— 该语句涉及 7 张核心业务表的复杂关联,因索引缺失导致全表扫描,最终引发交易系统阻塞。这类场景在传统数据库开发中屡见不鲜:据 Gartne…

【中间件】bthread效率为什么高?

bthread效率为什么更高&#xff1f; 1 基本概念 bthread是brpc中的用户态线程&#xff08;也可称为M:N线程库&#xff09;&#xff0c;目的是&#xff1a;提高程序的并发度&#xff0c;同时降低编码难度&#xff0c;在多核cpu上提供更好的scalability和cache locality。其采用…

DeepSeek V2:引入MLA机制与指令对齐

长上下文革命:Multi-Head Latent Attention(MLA)机制 传统 Transformer 的多头注意力需要缓存所有输入token的 Key 和 Value,这对长文本推理时的内存开销极为庞大。DeepSeek V2 针对这一难题提出了“Multi-Head Latent Attention”(MLA)机制。MLA 的核心思想是对多头注意…

Druid监控sql导致的内存溢出--内存分析工具MemoryAnalyzer(mat)

问题 druid监控sql在网页端显示&#xff0c;我的服务插入sql比较大&#xff0c;druid把执行过的sql保存在DruidDataSource类的成员变量JdbcDataSourceStat dataSourceStat&#xff1b; JdbcDataSourceStat类中的LinkedHashMap<String, JdbcSqlStat> sqlStatMap中&#…

《Python实战进阶》No45:性能分析工具 cProfile 与 line_profiler

Python实战进阶 No45&#xff1a;性能分析工具 cProfile 与 line_profiler 摘要 在AI模型开发中&#xff0c;代码性能直接影响训练效率和资源消耗。本节通过cProfile和line_profiler工具&#xff0c;实战演示如何定位Python代码中的性能瓶颈&#xff0c;并结合NumPy向量化操作…

计算机操作系统知识集合

主要来自小林coding 硬件结构 cpu位宽 如果用 32 位 CPU 去加和两个 64 位大小的数字&#xff0c;就需要把这 2 个 64 位的数字分成 2 个低位 32 位数字和 2 个高位 32 位数字来计算&#xff0c;先加个两个低位的 32 位数字&#xff0c;算出进位&#xff0c;然后加和两个高位…

电机常用易混淆概念说明(伺服、舵机、多轮)

1. 概述 基础动力需求 &#xff1a;普通电机&#xff08;如水泵、风扇&#xff09;。 高精度控制 &#xff1a;优先伺服系统或伺服电机&#xff08;如数控机床&#xff09;。 微型化场景 &#xff1a;舵机&#xff08;如遥控模型&#xff09;。 移动底盘 &#xff1a;单舵轮成…

进程与线程:04 内核线程

内核级线程概述 上一讲我们学习了用户级线程&#xff0c;了解了其切换和创建方式。用户级线程切换核心在于从一个栈变为两个栈&#xff0c;每个线程有自己的栈和线程控制块&#xff08;tcb&#xff09;&#xff0c;切换时先切换tcb再切换栈&#xff0c;创建时将切换的pc指针放…

信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(六)

个人笔记整理---仅供参考 第六章项目管理概论 6.1PMBOK的发展 6.2项目基本要素 组织过程资产指的是项目上的&#xff0c;国产数据库的使用----安保和安全指的是环境因素 6.3项目经理的角色 6.4价值驱动的项目管理知识体系

[蓝桥杯 2023 国 Python B] 划分 Java

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int[] arr new int[41];int sum 0;for (int i 1; i < 40; i) {arr[i] sc.nextInt();sum arr[i];}sc.close();int target sum / 2; // 最接近的两…

Redis05-进阶-主从

零、文章目录 Redis05-进阶-主从 1、搭建主从架构 &#xff08;1&#xff09;概述 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 &#xff08;2&#xff09;集群概况 我们搭建的主从…

小结:ipsec-ike

IPSec 手动配置与自动配置&#xff08;IKE动态协商&#xff09; 手动配置IPSec 逻辑图 #mermaid-svg-eNMnNEwnoTjF8fkV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-eNMnNEwnoTjF8fkV .error-icon{fill:#552222;}…

潇洒郎: 100% 成功搭建Docker私有镜像仓库并管理、删除镜像

1、Registry Web管理界面 2、拉取Registry-Web镜像 创建配置文件 tee /opt/zwx-registry/web-config.yml <<-EOF registry:url: http://172.28.73.90:8010/v2name: registryreadonly: falseauth:enabled: false EOF 拉取docker-registry-web镜像并绑定Registry仓库 …

《机器学习中的过拟合与模型复杂性:理解与应对策略》

《机器学习中的过拟合与模型复杂性&#xff1a;理解与应对策略》 摘要 在机器学习中&#xff0c;过拟合是模型在训练数据上表现良好但在新数据上泛化能力差的现象。本文深入探讨了过拟合与模型复杂性之间的关系&#xff0c;分析了复杂模型导致过拟合的原因&#xff0c;并介绍…