Spring Boot + MyBatisPlus快速實(shí)現(xiàn)單表CRUD的示例
在Spring Boot項(xiàng)目開發(fā)中,單表CRUD(新增Create、查詢Retrieve、修改Update、刪除Delete)是最基礎(chǔ)、最常用的操作。傳統(tǒng)MyBatis實(shí)現(xiàn)CRUD需要編寫大量XML映射文件和SQL語(yǔ)句,繁瑣且易出錯(cuò);而MyBatis-Plus(MP)作為MyBatis的增強(qiáng)工具,通過(guò)內(nèi)置接口和注解,實(shí)現(xiàn)了單表CRUD的“零XML、零SQL”極簡(jiǎn)開發(fā),新手也能快速上手。
本文基于「Spring Boot + MyBatis-Plus + MySQL」技術(shù)棧,全程貼合實(shí)戰(zhàn),從環(huán)境準(zhǔn)備、項(xiàng)目搭建、代碼編寫到測(cè)試驗(yàn)證,一步步教你快速實(shí)現(xiàn)單表CRUD,同時(shí)梳理高頻踩坑點(diǎn)和最佳實(shí)踐,確保你不僅能實(shí)現(xiàn)功能,還能規(guī)范編碼、規(guī)避問(wèn)題,適配日常開發(fā)場(chǎng)景。
前置說(shuō)明:本文默認(rèn)你已掌握「Spring Boot + MyBatis-Plus 連接MySQL」的基礎(chǔ)操作(數(shù)據(jù)庫(kù)連接、依賴導(dǎo)入),若未掌握,可先完成數(shù)據(jù)庫(kù)連接配置,再繼續(xù)本文內(nèi)容(文末附基礎(chǔ)連接補(bǔ)充)。
一、前置準(zhǔn)備(極簡(jiǎn)版,快速適配)
確保本地環(huán)境和項(xiàng)目依賴滿足要求,避免版本不兼容導(dǎo)致功能異常,直接照搬配置即可。
1. 環(huán)境要求
- JDK:1.8 及以上(優(yōu)先1.8,兼容性最佳);
- Spring Boot:2.7.x 穩(wěn)定版(新手避開3.x,減少語(yǔ)法差異踩坑);
- MyBatis-Plus:3.5.x 版本(與Spring Boot 2.7.x 完美適配);
- MySQL:5.7 / 8.0 版本(本文以MySQL 8.0為例,5.7僅驅(qū)動(dòng)配置有差異);
- 開發(fā)工具:IDEA(社區(qū)版)、MySQL客戶端(Navicat/Workbench);
- 輔助依賴:Lombok(簡(jiǎn)化實(shí)體類編寫,可選但強(qiáng)烈推薦)。
2. 核心依賴(pom.xml)
項(xiàng)目中需引入以下核心依賴,若已創(chuàng)建項(xiàng)目,核對(duì)并補(bǔ)充即可;若新建項(xiàng)目,IDEA勾選對(duì)應(yīng)選項(xiàng)自動(dòng)導(dǎo)入。
<!-- Spring Boot 核心啟動(dòng)器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis-Plus 啟動(dòng)器(核心,內(nèi)置MyBatis,無(wú)需單獨(dú)引入) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- MySQL 8.0 驅(qū)動(dòng) -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok(簡(jiǎn)化實(shí)體類,無(wú)需寫get/set、toString) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 測(cè)試依賴(用于測(cè)試CRUD功能) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>3. 數(shù)據(jù)庫(kù)與表準(zhǔn)備
提前創(chuàng)建測(cè)試數(shù)據(jù)庫(kù)和單表,本文以「用戶表(user)」為例,執(zhí)行以下SQL語(yǔ)句(MySQL客戶端中運(yùn)行),確保表結(jié)構(gòu)和字段與后續(xù)實(shí)體類對(duì)應(yīng)。
-- 1. 創(chuàng)建數(shù)據(jù)庫(kù)(名稱:mp_demo,可自定義,需與yml配置一致) CREATE DATABASE IF NOT EXISTS mp_demo DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; -- 2. 切換到目標(biāo)數(shù)據(jù)庫(kù) USE mp_demo; -- 3. 創(chuàng)建用戶表(user),單表CRUD測(cè)試用 CREATE TABLE IF NOT EXISTS `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID(自增)', `name` varchar(30) NOT NULL COMMENT '用戶姓名', `age` int(11) DEFAULT NULL COMMENT '用戶年齡', `email` varchar(50) DEFAULT NULL COMMENT '用戶郵箱', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶表';
4. 核心配置(application.yml)
編寫數(shù)據(jù)庫(kù)連接配置和MyBatis-Plus基礎(chǔ)配置,重點(diǎn)修改數(shù)據(jù)庫(kù)名稱、賬號(hào)、密碼,其余配置直接復(fù)用,確保CRUD操作能正常關(guān)聯(lián)數(shù)據(jù)庫(kù)。
# 服務(wù)器配置(可選,避免端口沖突)
server:
port: 8081
servlet:
context-path: /crud-demo
# 數(shù)據(jù)庫(kù)連接配置(核心,必須修改)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver # MySQL 8.0 驅(qū)動(dòng)類
url: jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
username: root # 你的MySQL賬號(hào)(默認(rèn)root)
password: 123456 # 你的MySQL密碼
# MyBatis-Plus 配置(簡(jiǎn)化CRUD關(guān)鍵)
mybatis-plus:
type-aliases-package: com.example.cruddemo.entity # 實(shí)體類包路徑(修改為你的包名)
mapper-locations: classpath:mapper/**/*.xml # 自定義SQL的XML路徑(本文暫用不到,預(yù)留)
configuration:
map-underscore-to-camel-case: true # 開啟下劃線轉(zhuǎn)駝峰(數(shù)據(jù)庫(kù)create_time → 實(shí)體類createTime)
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 開啟SQL日志打?。ū阌谡{(diào)試,查看執(zhí)行的SQL)
global-config:
db-config:
table-prefix: # 表前綴(若表名有前綴,如mp_user,此處填mp_,本文無(wú)前綴,留空)
id-type: AUTO # 主鍵自增策略(與數(shù)據(jù)庫(kù)表id自增對(duì)應(yīng))避坑提醒:若使用MySQL 5.7,需將驅(qū)動(dòng)類改為「com.mysql.jdbc.Driver」,并刪除url中的「serverTimezone=GMT%2B8」配置,驅(qū)動(dòng)依賴替換為mysql-connector-java:5.1.47。
二、核心代碼編寫(零XML、零SQL,快速實(shí)現(xiàn)CRUD)
MyBatis-Plus的核心優(yōu)勢(shì)的是「BaseMapper接口」和「IService接口」,兩者都內(nèi)置了完整的單表CRUD方法,無(wú)需手動(dòng)編寫SQL。本文分別演示兩種方式(新手優(yōu)先掌握BaseMapper,簡(jiǎn)化開發(fā);IService適合復(fù)雜業(yè)務(wù)場(chǎng)景)。
項(xiàng)目包結(jié)構(gòu)規(guī)范(必遵循,避免掃描失?。?/p>
com.example.cruddemo # 項(xiàng)目根包
├── CrudDemoApplication.java # 啟動(dòng)類
├── entity # 實(shí)體類包(對(duì)應(yīng)數(shù)據(jù)庫(kù)表)
│ └── User.java
├── mapper # Mapper接口包(繼承BaseMapper)
│ └── UserMapper.java
├── service # 服務(wù)層包(繼承IService,可選)
│ ├── UserService.java
│ └── impl
│ └── UserServiceImpl.java
└── controller # 控制層包(編寫接口,測(cè)試CRUD,可選)
└── UserController.java1. 第一步:編寫實(shí)體類(Entity)
實(shí)體類與數(shù)據(jù)庫(kù)表一一對(duì)應(yīng),通過(guò)Lombok簡(jiǎn)化代碼,通過(guò)MyBatis-Plus注解指定表名、主鍵策略等(若實(shí)體類名與表名一致、字段名與數(shù)據(jù)庫(kù)字段一致,部分注解可省略)。
package com.example.cruddemo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
/**
* 用戶實(shí)體類,對(duì)應(yīng)數(shù)據(jù)庫(kù)user表
*/
@Data // Lombok注解,自動(dòng)生成get/set、toString、equals等方法
@TableName("user") // 指定對(duì)應(yīng)數(shù)據(jù)庫(kù)表名(實(shí)體類名與表名一致時(shí),可省略)
public class User {
/**
* 主鍵ID,自增
* @TableId:指定主鍵,type=IdType.AUTO 對(duì)應(yīng)數(shù)據(jù)庫(kù)自增策略
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用戶名,對(duì)應(yīng)數(shù)據(jù)庫(kù)name字段
* 字段名與數(shù)據(jù)庫(kù)一致,無(wú)需額外注解
*/
private String name;
/**
* 年齡,對(duì)應(yīng)數(shù)據(jù)庫(kù)age字段
*/
private Integer age;
/**
* 郵箱,對(duì)應(yīng)數(shù)據(jù)庫(kù)email字段
*/
private String email;
/**
* 創(chuàng)建時(shí)間,對(duì)應(yīng)數(shù)據(jù)庫(kù)create_time字段
* @TableField:指定數(shù)據(jù)庫(kù)字段名(下劃線轉(zhuǎn)駝峰可省略,此處用于演示)
* fill = FieldFill.INSERT:插入時(shí)自動(dòng)填充時(shí)間(無(wú)需手動(dòng)設(shè)置)
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新時(shí)間,對(duì)應(yīng)數(shù)據(jù)庫(kù)update_time字段
* fill = FieldFill.INSERT_UPDATE:插入和更新時(shí)自動(dòng)填充時(shí)間
*/
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
2. 第二步:時(shí)間自動(dòng)填充配置(可選,優(yōu)化體驗(yàn))
實(shí)體類中createTime和updateTime字段配置了「自動(dòng)填充」,需編寫填充處理器,實(shí)現(xiàn)插入/更新時(shí)自動(dòng)填充當(dāng)前時(shí)間,無(wú)需手動(dòng)設(shè)置字段值。
package com.example.cruddemo.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* MyBatis-Plus 時(shí)間自動(dòng)填充處理器
*/
@Component // 交給Spring管理,必須添加該注解
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入時(shí)自動(dòng)填充
@Override
public void insertFill(MetaObject metaObject) {
// 填充createTime和updateTime字段,值為當(dāng)前時(shí)間
strictInsertFill(metaObject, "createTime", Date.class, new Date());
strictInsertFill(metaObject, "updateTime", Date.class, new Date());
}
// 更新時(shí)自動(dòng)填充
@Override
public void updateFill(MetaObject metaObject) {
// 只填充updateTime字段,值為當(dāng)前時(shí)間
strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
3. 方式1:基于BaseMapper實(shí)現(xiàn)CRUD(新手首選)
BaseMapper是MyBatis-Plus提供的基礎(chǔ)Mapper接口,內(nèi)置了完整的單表CRUD方法(insert、selectById、selectList、updateById、deleteById等),只需讓自定義Mapper接口繼承BaseMapper,無(wú)需編寫任何方法,即可直接使用。
3.1 編寫Mapper接口
package com.example.cruddemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.cruddemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
/**
* UserMapper接口,繼承BaseMapper,實(shí)現(xiàn)單表CRUD
* @Mapper:標(biāo)記為MyBatis-Plus的Mapper接口,讓Spring Boot自動(dòng)掃描
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 無(wú)需編寫任何方法!BaseMapper已內(nèi)置所有單表CRUD方法
}
3.2 啟動(dòng)類添加Mapper掃描(關(guān)鍵避坑)
打開項(xiàng)目啟動(dòng)類,添加@MapperScan注解,指定Mapper接口所在的包路徑,否則Spring Boot無(wú)法掃描到Mapper接口,會(huì)導(dǎo)致注入失敗。
package com.example.cruddemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.cruddemo.mapper") // 掃描Mapper接口包(修改為你的包名)
public class CrudDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CrudDemoApplication.class, args);
}
}
3.3 BaseMapper核心CRUD方法(常用,必記)
BaseMapper內(nèi)置了數(shù)十種方法,以下是單表CRUD最常用的方法,直接調(diào)用即可,無(wú)需寫SQL:
| 方法名 | 功能描述 | 示例 |
|---|---|---|
| insert(T entity) | 新增一條數(shù)據(jù)(返回影響行數(shù)) | userMapper.insert(user); |
| selectById(Serializable id) | 根據(jù)主鍵ID查詢一條數(shù)據(jù) | userMapper.selectById(1L); |
| selectList(QueryWrapper queryWrapper) | 查詢所有數(shù)據(jù)(可加條件) | userMapper.selectList(null);(查詢所有) |
| updateById(T entity) | 根據(jù)主鍵ID修改數(shù)據(jù)(非null字段才修改) | userMapper.updateById(user); |
| deleteById(Serializable id) | 根據(jù)主鍵ID刪除一條數(shù)據(jù) | userMapper.deleteById(1L); |
| selectCount(QueryWrapper queryWrapper) | 統(tǒng)計(jì)數(shù)據(jù)條數(shù)(可加條件) | userMapper.selectCount(null);(統(tǒng)計(jì)所有) |
4. 方式2:基于IService實(shí)現(xiàn)CRUD(適合業(yè)務(wù)層開發(fā))
IService是MyBatis-Plus提供的服務(wù)層接口,基于BaseMapper封裝,提供了更豐富的CRUD方法(如批量操作、分頁(yè)查詢),還支持自定義業(yè)務(wù)邏輯,適合實(shí)際開發(fā)中的服務(wù)層編寫(推薦項(xiàng)目開發(fā)使用)。
4.1 編寫Service接口(繼承IService)
package com.example.cruddemo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.cruddemo.entity.User;
/**
* UserService接口,繼承IService,封裝CRUD方法和業(yè)務(wù)邏輯
*/
public interface UserService extends IService<User> {
// 此處可添加自定義業(yè)務(wù)方法(如根據(jù)姓名查詢用戶),基礎(chǔ)CRUD方法IService已內(nèi)置
}
4.2 編寫Service實(shí)現(xiàn)類(繼承ServiceImpl)
package com.example.cruddemo.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.cruddemo.entity.User;
import com.example.cruddemo.mapper.UserMapper;
import com.example.cruddemo.service.UserService;
import org.springframework.stereotype.Service;
/**
* Service實(shí)現(xiàn)類,繼承ServiceImpl,關(guān)聯(lián)Mapper和Entity
* @Service:標(biāo)記為Spring服務(wù)層組件,交給Spring管理
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// 基礎(chǔ)CRUD方法無(wú)需編寫,IService/ServiceImpl已內(nèi)置
// 示例:自定義業(yè)務(wù)方法(根據(jù)姓名查詢用戶,后續(xù)可擴(kuò)展)
/*
public User selectByName(String name) {
// 用QueryWrapper構(gòu)建查詢條件(下文會(huì)演示)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", name);
return baseMapper.selectOne(queryWrapper);
}
*/
}
4.3 IService核心CRUD方法(常用)
IService在BaseMapper基礎(chǔ)上做了增強(qiáng),新增了批量操作、分頁(yè)等方法,常用方法如下:
- 新增:save(T entity)(等同于insert)、saveBatch(Collection entityList)(批量新增);
- 查詢:getById(Serializable id)(等同于selectById)、list()(查詢所有)、count()(統(tǒng)計(jì)條數(shù));
- 修改:updateById(T entity)(等同于updateById)、updateBatchById(Collection entityList)(批量修改);
- 刪除:removeById(Serializable id)(等同于deleteById)、removeBatchByIds(Collection<?> idList)(批量刪除)。
三、測(cè)試驗(yàn)證(兩種方式,確保CRUD功能正常)
本文通過(guò)「Spring Boot測(cè)試類」直接測(cè)試CRUD功能,無(wú)需編寫接口,簡(jiǎn)單高效;后續(xù)也可通過(guò)控制層編寫接口,用Postman測(cè)試(文末附控制層示例)。
1. 測(cè)試BaseMapper方式(新手優(yōu)先)
在test目錄下,找到默認(rèn)的測(cè)試類,注入U(xiǎn)serMapper,編寫測(cè)試方法,逐一驗(yàn)證CRUD功能。
package com.example.cruddemo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.cruddemo.entity.User;
import com.example.cruddemo.mapper.UserMapper;
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 // 標(biāo)記為Spring Boot測(cè)試類,啟動(dòng)Spring容器
class CrudDemoApplicationTests {
// 自動(dòng)注入U(xiǎn)serMapper(Spring掃描@Mapper注解后,自動(dòng)創(chuàng)建實(shí)例)
@Autowired
private UserMapper userMapper;
/**
* 測(cè)試1:新增用戶(Create)
*/
@Test
void testInsert() {
// 創(chuàng)建User對(duì)象,無(wú)需設(shè)置id(自增)、createTime、updateTime(自動(dòng)填充)
User user = new User();
user.setName("張三");
user.setAge(22);
user.setEmail("zhangsan@163.com");
// 調(diào)用BaseMapper的insert方法,新增數(shù)據(jù)
int rows = userMapper.insert(user);
System.out.println("新增成功,影響行數(shù):" + rows);
System.out.println("新增用戶ID:" + user.getId()); // 新增后,自增ID會(huì)自動(dòng)回顯
}
/**
* 測(cè)試2:根據(jù)ID查詢用戶(Retrieve)
*/
@Test
void testSelectById() {
// 調(diào)用selectById方法,根據(jù)ID查詢(ID為新增時(shí)回顯的ID,可修改為自己的)
User user = userMapper.selectById(1L);
System.out.println("查詢到的用戶信息:" + user);
}
/**
* 測(cè)試3:查詢所有用戶 + 條件查詢(Retrieve)
*/
@Test
void testSelectList() {
// 1. 查詢所有用戶(無(wú)條件,queryWrapper傳null)
List<User> allUser = userMapper.selectList(null);
System.out.println("所有用戶:" + allUser);
// 2. 條件查詢(示例:查詢年齡>20的用戶)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20); // gt表示“大于”,eq表示“等于”,lt表示“小于”
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println("年齡大于20的用戶:" + userList);
}
/**
* 測(cè)試4:根據(jù)ID修改用戶(Update)
*/
@Test
void testUpdateById() {
// 1. 先查詢要修改的用戶(確保用戶存在)
User user = userMapper.selectById(1L);
// 2. 修改用戶信息(僅修改非null字段)
user.setAge(23); // 修改年齡
user.setEmail("zhangsan_update@163.com"); // 修改郵箱
// 3. 調(diào)用updateById方法,修改數(shù)據(jù)
int rows = userMapper.updateById(user);
System.out.println("修改成功,影響行數(shù):" + rows);
}
/**
* 測(cè)試5:根據(jù)ID刪除用戶(Delete)
*/
@Test
void testDeleteById() {
// 調(diào)用deleteById方法,根據(jù)ID刪除(ID為要?jiǎng)h除的用戶ID,謹(jǐn)慎操作)
int rows = userMapper.deleteById(1L);
System.out.println("刪除成功,影響行數(shù):" + rows);
}
}
2. 測(cè)試IService方式(服務(wù)層測(cè)試)
注入U(xiǎn)serService,測(cè)試IService內(nèi)置的CRUD方法,用法與BaseMapper類似,更貼合實(shí)際業(yè)務(wù)開發(fā)。
package com.example.cruddemo;
import com.example.cruddemo.entity.User;
import com.example.cruddemo.service.UserService;
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 UserServiceTest {
// 自動(dòng)注入U(xiǎn)serService(@Service注解標(biāo)記,Spring自動(dòng)管理)
@Autowired
private UserService userService;
// 測(cè)試新增
@Test
void testSave() {
User user = new User();
user.setName("李四");
user.setAge(25);
user.setEmail("lisi@163.com");
boolean success = userService.save(user); // IService返回boolean,更直觀
System.out.println("新增是否成功:" + success);
}
// 測(cè)試查詢所有
@Test
void testList() {
List<User> userList = userService.list();
System.out.println("所有用戶:" + userList);
}
// 測(cè)試修改
@Test
void testUpdateById() {
User user = new User();
user.setId(2L); // 必須設(shè)置ID,否則無(wú)法修改
user.setAge(26);
boolean success = userService.updateById(user);
System.out.println("修改是否成功:" + success);
}
// 測(cè)試刪除
@Test
void testRemoveById() {
boolean success = userService.removeById(2L);
System.out.println("刪除是否成功:" + success);
}
// 測(cè)試批量新增(IService增強(qiáng)方法)
@Test
void testSaveBatch() {
User user1 = new User();
user1.setName("王五");
user1.setAge(28);
user1.setEmail("wangwu@163.com");
User user2 = new User();
user2.setName("趙六");
user2.setAge(30);
user2.setEmail("zhaoliu@163.com");
List<User> userList = List.of(user1, user2);
boolean success = userService.saveBatch(userList);
System.out.println("批量新增是否成功:" + success);
}
}
3. 測(cè)試成功標(biāo)志
- 運(yùn)行所有測(cè)試方法,控制臺(tái)無(wú)紅色報(bào)錯(cuò);
- SQL日志正常打?。ㄩ_啟了log-impl配置),能看到自動(dòng)生成的SQL語(yǔ)句;
- 打開MySQL客戶端,查詢user表,能看到新增、修改、刪除后的對(duì)應(yīng)數(shù)據(jù);
- 條件查詢、批量操作能返回正確結(jié)果。
四、可選擴(kuò)展:編寫控制層接口(Postman測(cè)試)
實(shí)際開發(fā)中,CRUD功能通常通過(guò)接口對(duì)外提供,這里編寫簡(jiǎn)單的RESTful接口,用Postman測(cè)試,貼合真實(shí)開發(fā)場(chǎng)景。
package com.example.cruddemo.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.cruddemo.entity.User;
import com.example.cruddemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用戶控制層,編寫CRUD接口
* @RestController:等同于@Controller + @ResponseBody,返回JSON數(shù)據(jù)
* @RequestMapping:接口統(tǒng)一前綴
*/
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
// 1. 新增用戶(POST請(qǐng)求)
@PostMapping("/add")
public String addUser(@RequestBody User user) {
boolean success = userService.save(user);
return success ? "新增成功" : "新增失敗";
}
// 2. 根據(jù)ID查詢用戶(GET請(qǐng)求)
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getById(id);
}
// 3. 查詢所有用戶(GET請(qǐng)求)
@GetMapping("/list")
public List<User> getUserList() {
return userService.list();
}
// 4. 根據(jù)ID修改用戶(PUT請(qǐng)求)
@PutMapping("/update")
public String updateUser(@RequestBody User user) {
boolean success = userService.updateById(user);
return success ? "修改成功" : "修改失敗";
}
// 5. 根據(jù)ID刪除用戶(DELETE請(qǐng)求)
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
boolean success = userService.removeById(id);
return success ? "刪除成功" : "刪除失敗";
}
// 6. 條件查詢(示例:根據(jù)姓名查詢)
@GetMapping("/list/name")
public List<User> getUserByName(@RequestParam String name) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", name);
return userService.list(queryWrapper);
}
}
接口測(cè)試方法:?jiǎn)?dòng)項(xiàng)目,打開Postman,根據(jù)接口請(qǐng)求方式(POST/PUT/GET/DELETE),輸入接口地址(如 http://localhost:8081/crud-demo/api/user/add),傳遞參數(shù),即可測(cè)試CRUD功能。
五、高頻踩坑點(diǎn)匯總(新手必看,規(guī)避90%問(wèn)題)
整理了新手實(shí)現(xiàn)單表CRUD時(shí)最常遇到的6個(gè)問(wèn)題,每個(gè)問(wèn)題附上根因和解決方案,遇到報(bào)錯(cuò)直接對(duì)照排查,快速解決。
踩坑1:Mapper注入失?。∟o qualifying bean of type ‘xxxMapper’ available)
? 報(bào)錯(cuò)原因:?jiǎn)?dòng)類未添加@MapperScan注解,或注解中的包路徑錯(cuò)誤;Mapper接口未添加@Mapper注解。
? 解決方案:?jiǎn)?dòng)類添加@MapperScan(“com.example.cruddemo.mapper”);確保Mapper接口添加@Mapper注解;核對(duì)包路徑,確保一致。
踩坑2:新增/修改后,時(shí)間字段未自動(dòng)填充
? 報(bào)錯(cuò)原因:未編寫時(shí)間自動(dòng)填充處理器(MyMetaObjectHandler);處理器未添加@Component注解,未被Spring管理;實(shí)體類字段的@TableField(fill = …)配置錯(cuò)誤。
? 解決方案:編寫MyMetaObjectHandler類,添加@Component注解;核對(duì)實(shí)體類字段的fill屬性,insert對(duì)應(yīng)INSERT,update對(duì)應(yīng)INSERT_UPDATE。
踩坑3:修改數(shù)據(jù)無(wú)效,無(wú)報(bào)錯(cuò)
? 報(bào)錯(cuò)原因:修改時(shí)未設(shè)置實(shí)體類的id字段(MyBatis-Plus根據(jù)id修改);實(shí)體類所有字段為null,無(wú)修改內(nèi)容;數(shù)據(jù)庫(kù)表主鍵不是id,或主鍵策略配置錯(cuò)誤。
? 解決方案:修改時(shí)必須設(shè)置實(shí)體類的id;確保至少有一個(gè)非null字段需要修改;核對(duì)yml中mybatis-plus.global-config.db-config.id-type配置,與數(shù)據(jù)庫(kù)主鍵策略一致。
踩坑4:條件查詢無(wú)結(jié)果,SQL日志顯示條件錯(cuò)誤
? 報(bào)錯(cuò)原因:QueryWrapper構(gòu)建條件時(shí),字段名與數(shù)據(jù)庫(kù)字段不一致;未開啟下劃線轉(zhuǎn)駝峰配置,導(dǎo)致字段匹配失敗(如createTime對(duì)應(yīng)create_time)。
? 解決方案:QueryWrapper中使用數(shù)據(jù)庫(kù)字段名(如name、age),而非實(shí)體類駝峰名;確保yml中開啟map-underscore-to-camel-case: true。
踩坑5:Service注入失?。∟o qualifying bean of type ‘xxxService’ available)
? 報(bào)錯(cuò)原因:Service實(shí)現(xiàn)類未添加@Service注解;Service接口未繼承IService,或?qū)崿F(xiàn)類未繼承ServiceImpl。
? 解決方案:Service實(shí)現(xiàn)類添加@Service注解;確保UserService繼承IService,UserServiceImpl繼承ServiceImpl<UserMapper, User>。
踩坑6:SQL日志不打印,無(wú)法調(diào)試
? 報(bào)錯(cuò)原因:未開啟MyBatis-Plus的SQL日志打印配置;log-impl配置路徑錯(cuò)誤。
? 解決方案:在yml的mybatis-plus.configuration中,添加log-impl: org.apache.ibatis.logging.stdout.StdOutImpl。
六、補(bǔ)充:BaseMapper vs IService 選擇建議
很多新手會(huì)糾結(jié)兩種方式的選擇,結(jié)合實(shí)際開發(fā)場(chǎng)景,給出明確建議,避免選型困惑:
- 新手入門、簡(jiǎn)單測(cè)試:優(yōu)先使用BaseMapper,代碼更簡(jiǎn)潔,無(wú)需編寫Service層,快速實(shí)現(xiàn)CRUD;
- 實(shí)際項(xiàng)目開發(fā):優(yōu)先使用IService+ServiceImpl,封裝服務(wù)層,便于添加自定義業(yè)務(wù)邏輯,支持批量操作、分頁(yè)查詢等增強(qiáng)功能,符合分層開發(fā)規(guī)范(Controller → Service → Mapper);
- 核心區(qū)別:IService基于BaseMapper封裝,功能更豐富,返回值更直觀(如boolean表示操作結(jié)果),適合業(yè)務(wù)場(chǎng)景;BaseMapper更偏向底層,適合簡(jiǎn)單場(chǎng)景。
七、總結(jié)
Spring Boot + MyBatis-Plus 實(shí)現(xiàn)單表CRUD的核心,就是“復(fù)用MyBatis-Plus內(nèi)置接口”,無(wú)需編寫XML和SQL,極大簡(jiǎn)化了開發(fā)流程,核心步驟可總結(jié)為3步:
- 準(zhǔn)備工作:導(dǎo)入核心依賴、配置數(shù)據(jù)庫(kù)連接、創(chuàng)建數(shù)據(jù)庫(kù)表;
- 核心編碼:編寫實(shí)體類(關(guān)聯(lián)數(shù)據(jù)庫(kù)表)、Mapper接口(繼承BaseMapper)、Service層(可選,繼承IService);
- 測(cè)試驗(yàn)證:通過(guò)測(cè)試類或接口,驗(yàn)證新增、查詢、修改、刪除功能正常。
本文覆蓋了新手實(shí)現(xiàn)單表CRUD的全流程,從基礎(chǔ)配置到進(jìn)階用法,從測(cè)試驗(yàn)證到踩坑排查,貼合實(shí)戰(zhàn)場(chǎng)景,新手只需跟著步驟操作,就能快速上手。后續(xù)可基于此基礎(chǔ),學(xué)習(xí)MyBatis-Plus的高級(jí)特性(條件構(gòu)造器、分頁(yè)插件、自動(dòng)生成代碼),進(jìn)一步提高開發(fā)效率。
若遇到其他問(wèn)題,可對(duì)照本文踩坑點(diǎn)排查,或留言交流,助力你快速搞定單表CRUD開發(fā)!
到此這篇關(guān)于Spring Boot + MyBatisPlus快速實(shí)現(xiàn)單表CRUD的示例的文章就介紹到這了,更多相關(guān)SpringBoot MyBatisPlus 單表CRUD內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot Mybatis Plus公共字段自動(dòng)填充功能
- springboot下mybatis-plus開啟打印sql日志的配置指南
- springboot集成mybatis-plus遇到的問(wèn)題及解決方法
- SpringBoot整合MyBatisPlus配置動(dòng)態(tài)數(shù)據(jù)源的方法
- Springboot mybatis-plus配置及用法詳解
- springboot+mybatis-plus實(shí)現(xiàn)自動(dòng)建表的示例
- springboot整合mybatis-plus 實(shí)現(xiàn)分頁(yè)查詢功能
- oracle+mybatis-plus+springboot實(shí)現(xiàn)分頁(yè)查詢的實(shí)例
相關(guān)文章
SpringBoot3整合SpringSecurity6快速入門示例教程
SpringSecurity 是Spring大家族中一名重要成員,是專門負(fù)責(zé)安全的框架,本文給大家介紹SpringBoot3整合SpringSecurity6快速入門示例教程,感興趣的朋友一起看看吧2025-04-04
Java移除無(wú)效括號(hào)的方法實(shí)現(xiàn)
本文主要介紹了Java移除無(wú)效括號(hào)的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
SpringBoot如何實(shí)現(xiàn)Tomcat自動(dòng)配置
這篇文章主要介紹了SpringBoot如何實(shí)現(xiàn)Tomcat自動(dòng)配置,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot框架,感興趣的朋友可以了解下2021-03-03
Java微信二次開發(fā)(一) Java微信請(qǐng)求驗(yàn)證功能
這篇文章主要為大家詳細(xì)介紹了Java微信二次開發(fā)第一篇,Java微信請(qǐng)求驗(yàn)證功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Jrebel License Server 激活 IDEA-Jrebel-在線-
這篇文章主要介紹了Jrebel License Server 激活 IDEA-Jrebel-在線-離線-均適用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
java設(shè)計(jì)模式之實(shí)現(xiàn)對(duì)象池模式示例分享
對(duì)象池模式經(jīng)常用在頻繁創(chuàng)建、銷毀對(duì)象(并且對(duì)象創(chuàng)建、銷毀開銷很大)的場(chǎng)景,比如數(shù)據(jù)庫(kù)連接池、線程池、任務(wù)隊(duì)列池等。本代碼簡(jiǎn)單,沒有限制對(duì)象池大小2014-02-02

