之前的Maven項目和本次需要的環境配置并不一樣
之前使用的是:
-
傳統的 MyBatis 框架(非 Spring Boot 環境)
-
手動管理
SqlSession
-
使用了
.xml
的 Mapper 映射文件 -
沒有 Spring 容器管理(沒有
@Service
/@RestController
等) -
沒有看到分頁插件配置,也沒有 REST 接口入口
項目結構對比 | 你現在的項目 | 實驗要求的項目 |
---|---|---|
框架風格 | 手動搭建的原生 MyBatis | Spring 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>
接口:提供了更高層級的封裝,比如
getById
、save
、removeById
等,默認自帶 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/setter 或 Lombok 注解 @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的問題,全部手動設置構造函數就解決了
“按商品名稱、多級類別、品牌查詢商品”的業務邏輯。
需要修改的類是:ProductServiceImpl
和 ProductController
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 | 實體類,對應數據庫字段 |
ProductMapper | Mapper接口,繼承自 BaseMapper |
IProductService | 服務接口,繼承 IService,并聲明 searchProducts 方法 |
ProductServiceImpl | 服務實現,繼承 ServiceImpl,實現自定義搜索邏輯 |
ProductController | 控制器,定義 /page 與 /search 兩個查詢接口 |
重點接口功能
/api/products/page
-
基礎分頁查詢,支持按
name
模糊搜索(如:?name=小米
)
/api/products/search
-
高級組合條件查詢:支持傳入
name
、category_level1
、category_level2
、category_level3
、brand