最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot + MyBatisPlus快速實(shí)現(xiàn)單表CRUD的示例

 更新時(shí)間:2026年06月05日 08:35:03   作者:碼客日記  
本文主要介紹了Spring Boot + MyBatisPlus快速實(shí)現(xiàn)單表CRUD的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在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.java

1. 第一步:編寫實(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)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java制作智能拼圖游戲原理及代碼

    Java制作智能拼圖游戲原理及代碼

    本文給大家分享的是使用Java實(shí)現(xiàn)智能拼圖游戲的原理,以及實(shí)現(xiàn)的源碼,推薦給大家,有需要的小伙伴可以參考下。
    2015-03-03
  • @Async異步線程池以及線程的命名方式

    @Async異步線程池以及線程的命名方式

    這篇文章主要介紹了@Async異步線程池以及線程的命名方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring Properties的使用和配置方法

    Spring Properties的使用和配置方法

    這篇文章主要介紹了Spring Properties的使用和配置方法,本文不是原理分析、源碼分析文章,只是希望可以幫助讀者更好地理解和使用 Spring Properties,有興趣的可以了解一下
    2018-01-01
  • SpringBoot3整合SpringSecurity6快速入門示例教程

    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)

    本文主要介紹了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)配置

    這篇文章主要介紹了SpringBoot如何實(shí)現(xiàn)Tomcat自動(dòng)配置,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot框架,感興趣的朋友可以了解下
    2021-03-03
  • Java微信二次開發(fā)(一) Java微信請(qǐng)求驗(yàn)證功能

    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-在線-

    這篇文章主要介紹了Jrebel License Server 激活 IDEA-Jrebel-在線-離線-均適用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java中indexOf()的用法小結(jié)

    Java中indexOf()的用法小結(jié)

    這篇文章主要介紹了Java中indexOf()的用法小結(jié),indexOf()有四種方法,用來(lái)查找某個(gè)字符或字符串的位置,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • java設(shè)計(jì)模式之實(shí)現(xiàn)對(duì)象池模式示例分享

    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

最新評(píng)論

萝北县| 咸宁市| 台东县| 兴化市| 乌拉特前旗| 七台河市| 三都| 烟台市| 克什克腾旗| 三穗县| 石家庄市| 三都| 临澧县| 靖西县| 元江| 尼木县| 泰来县| 胶南市| 灵川县| 凤冈县| 九龙县| 基隆市| 舟曲县| 兴文县| 临泉县| 木兰县| 上栗县| 阳山县| 太仆寺旗| 乌拉特前旗| 潢川县| 长汀县| 张家口市| 繁峙县| 西乌珠穆沁旗| 双峰县| 水富县| 盖州市| 历史| 宿松县| 宜兰市|