Spring Boot + MyBatis-Plus 快速实现单表 CRUD

JeecgBoot低代码平台:AI驱动的企业级开发实践 低代码开发平台通过可视化配置和代码生成技术,显著提升企业应用开发效率。其核心原理是将传统编码转化为模块化组件拼装,结合AI技术实现自然语言到代码的转换。JeecgBoot作为国内领先的低代码平台,采用Spring Boot+Vue3技术栈,支持AI自动生成前后端代码和数据库结构。该平台特别适合快速构建CRM、OA等业务系统,其内置的AI Skills技术能理解开发者需求描述,5分钟即可生成基础CRUD功能。通过集成ChatGPT等大模型,平台还提供智能问答、流程编排等AI应用能力,是数字化转型的理想工具。 阅读详情

Spring Boot + MyBatis-Plus 快速实现单表 CRUD

在Spring Boot项目开发中,单表CRUD(新增Create、查询Retrieve、修改Update、删除Delete)是最基础、最常用的操作。传统MyBatis实现CRUD需要编写大量XML映射文件和SQL语句,繁琐且易出错;而MyBatis-Plus(MP)作为MyBatis的增强工具,通过内置接口和注解,实现了单表CRUD的“零XML、零SQL”极简开发,新手也能快速上手。

本文基于「Spring Boot + MyBatis-Plus + MySQL」技术栈,全程贴合实战,从环境准备、项目搭建、代码编写到测试验证,一步步教你快速实现单表CRUD,同时梳理高频踩坑点和最佳实践,确保你不仅能实现功能,还能规范编码、规避问题,适配日常开发场景。

前置说明:本文默认你已掌握「Spring Boot + MyBatis-Plus 连接MySQL」的基础操作(数据库连接、依赖导入),若未掌握,可先完成数据库连接配置,再继续本文内容(文末附基础连接补充)。

一、前置准备(极简版,快速适配)

确保本地环境和项目依赖满足要求,避免版本不兼容导致功能异常,直接照搬配置即可。

1. 环境要求

  • JDK:1.8 及以上(优先1.8,兼容性最佳);

  • Spring Boot:2.7.x 稳定版(新手避开3.x,减少语法差异踩坑);

  • MyBatis-Plus:3.5.x 版本(与Spring Boot 2.7.x 完美适配);

  • MySQL:5.7 / 8.0 版本(本文以MySQL 8.0为例,5.7仅驱动配置有差异);

  • 开发工具:IDEA(社区版)、MySQL客户端(Navicat/Workbench);

  • 辅助依赖:Lombok(简化实体类编写,可选但强烈推荐)。

2. 核心依赖(pom.xml)

项目中需引入以下核心依赖,若已创建项目,核对并补充即可;若新建项目,IDEA勾选对应选项自动导入。

<!-- Spring Boot 核心启动器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- MyBatis-Plus 启动器(核心,内置MyBatis,无需单独引入) -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

<!-- MySQL 8.0 驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- Lombok(简化实体类,无需写get/set、toString) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

<!-- 测试依赖(用于测试CRUD功能) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

3. 数据库与表准备

提前创建测试数据库和单表,本文以「用户表(user)」为例,执行以下SQL语句(MySQL客户端中运行),确保表结构和字段与后续实体类对应。

-- 1. 创建数据库(名称:mp_demo,可自定义,需与yml配置一致)
CREATE DATABASE IF NOT EXISTS mp_demo 
DEFAULT CHARACTER SET utf8mb4 
DEFAULT COLLATE utf8mb4_general_ci;

-- 2. 切换到目标数据库
USE mp_demo;

-- 3. 创建用户表(user),单表CRUD测试用
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 '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

4. 核心配置(application.yml)

编写数据库连接配置和MyBatis-Plus基础配置,重点修改数据库名称、账号、密码,其余配置直接复用,确保CRUD操作能正常关联数据库。

# 服务器配置(可选,避免端口冲突)
server:
  port: 8081
  servlet:
    context-path: /crud-demo

# 数据库连接配置(核心,必须修改)
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver  # MySQL 8.0 驱动类
    url: jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
    username: root  # 你的MySQL账号(默认root)
    password: 123456  # 你的MySQL密码

# MyBatis-Plus 配置(简化CRUD关键)
mybatis-plus:
  type-aliases-package: com.example.cruddemo.entity  # 实体类包路径(修改为你的包名)
  mapper-locations: classpath:mapper/**/*.xml  # 自定义SQL的XML路径(本文暂用不到,预留)
  configuration:
    map-underscore-to-camel-case: true  # 开启下划线转驼峰(数据库create_time → 实体类createTime)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 开启SQL日志打印(便于调试,查看执行的SQL)
  global-config:
    db-config:
      table-prefix:  # 表前缀(若表名有前缀,如mp_user,此处填mp_,本文无前缀,留空)
      id-type: AUTO  # 主键自增策略(与数据库表id自增对应)

避坑提醒:若使用MySQL 5.7,需将驱动类改为「com.mysql.jdbc.Driver」,并删除url中的「serverTimezone=GMT%2B8」配置,驱动依赖替换为mysql-connector-java:5.1.47。

二、核心代码编写(零XML、零SQL,快速实现CRUD)

MyBatis-Plus的核心优势的是「BaseMapper接口」和「IService接口」,两者都内置了完整的单表CRUD方法,无需手动编写SQL。本文分别演示两种方式(新手优先掌握BaseMapper,简化开发;IService适合复杂业务场景)。

项目包结构规范(必遵循,避免扫描失败):

com.example.cruddemo  # 项目根包
├── CrudDemoApplication.java  # 启动类
├── entity  # 实体类包(对应数据库表)
│   └── User.java
├── mapper  # Mapper接口包(继承BaseMapper)
│   └── UserMapper.java
├── service  # 服务层包(继承IService,可选)
│   ├── UserService.java
│   └── impl
│       └── UserServiceImpl.java
└── controller  # 控制层包(编写接口,测试CRUD,可选)
    └── UserController.java

1. 第一步:编写实体类(Entity)

实体类与数据库表一一对应,通过Lombok简化代码,通过MyBatis-Plus注解指定表名、主键策略等(若实体类名与表名一致、字段名与数据库字段一致,部分注解可省略)。

package com.example.cruddemo.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;

/**
 * 用户实体类,对应数据库user表
 */
@Data  // Lombok注解,自动生成get/set、toString、equals等方法
@TableName("user")  // 指定对应数据库表名(实体类名与表名一致时,可省略)
public class User {

    /**
     * 主键ID,自增
     * @TableId:指定主键,type=IdType.AUTO 对应数据库自增策略
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户名,对应数据库name字段
     * 字段名与数据库一致,无需额外注解
     */
    private String name;

    /**
     * 年龄,对应数据库age字段
     */
    private Integer age;

    /**
     * 邮箱,对应数据库email字段
     */
    private String email;

    /**
     * 创建时间,对应数据库create_time字段
     * @TableField:指定数据库字段名(下划线转驼峰可省略,此处用于演示)
     * fill = FieldFill.INSERT:插入时自动填充时间(无需手动设置)
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;

    /**
     * 更新时间,对应数据库update_time字段
     * fill = FieldFill.INSERT_UPDATE:插入和更新时自动填充时间
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

2. 第二步:时间自动填充配置(可选,优化体验)

实体类中createTime和updateTime字段配置了「自动填充」,需编写填充处理器,实现插入/更新时自动填充当前时间,无需手动设置字段值。

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 时间自动填充处理器
 */
@Component  // 交给Spring管理,必须添加该注解
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 插入时自动填充
    @Override
    public void insertFill(MetaObject metaObject) {
        // 填充createTime和updateTime字段,值为当前时间
        strictInsertFill(metaObject, "createTime", Date.class, new Date());
        strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }

    // 更新时自动填充
    @Override
    public void updateFill(MetaObject metaObject) {
        // 只填充updateTime字段,值为当前时间
        strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

3. 方式1:基于BaseMapper实现CRUD(新手首选)

BaseMapper是MyBatis-Plus提供的基础Mapper接口,内置了完整的单表CRUD方法(insert、selectById、selectList、updateById、deleteById等),只需让自定义Mapper接口继承BaseMapper,无需编写任何方法,即可直接使用。

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,实现单表CRUD
 * @Mapper:标记为MyBatis-Plus的Mapper接口,让Spring Boot自动扫描
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 无需编写任何方法!BaseMapper已内置所有单表CRUD方法
}
3.2 启动类添加Mapper扫描(关键避坑)

打开项目启动类,添加@MapperScan注解,指定Mapper接口所在的包路径,否则Spring Boot无法扫描到Mapper接口,会导致注入失败。

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内置了数十种方法,以下是单表CRUD最常用的方法,直接调用即可,无需写SQL:

方法名功能描述示例
insert(T entity)新增一条数据(返回影响行数)userMapper.insert(user);
selectById(Serializable id)根据主键ID查询一条数据userMapper.selectById(1L);
selectList(QueryWrapper queryWrapper)查询所有数据(可加条件)userMapper.selectList(null);(查询所有)
updateById(T entity)根据主键ID修改数据(非null字段才修改)userMapper.updateById(user);
deleteById(Serializable id)根据主键ID删除一条数据userMapper.deleteById(1L);
selectCount(QueryWrapper queryWrapper)统计数据条数(可加条件)userMapper.selectCount(null);(统计所有)

4. 方式2:基于IService实现CRUD(适合业务层开发)

IService是MyBatis-Plus提供的服务层接口,基于BaseMapper封装,提供了更丰富的CRUD方法(如批量操作、分页查询),还支持自定义业务逻辑,适合实际开发中的服务层编写(推荐项目开发使用)。

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方法和业务逻辑
 */
public interface UserService extends IService<User> {
    // 此处可添加自定义业务方法(如根据姓名查询用户),基础CRUD方法IService已内置
}
4.2 编写Service实现类(继承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实现类,继承ServiceImpl,关联Mapper和Entity
 * @Service:标记为Spring服务层组件,交给Spring管理
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    // 基础CRUD方法无需编写,IService/ServiceImpl已内置
    // 示例:自定义业务方法(根据姓名查询用户,后续可扩展)
    /*
    public User selectByName(String name) {
        // 用QueryWrapper构建查询条件(下文会演示)
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        return baseMapper.selectOne(queryWrapper);
    }
    */
}
4.3 IService核心CRUD方法(常用)

IService在BaseMapper基础上做了增强,新增了批量操作、分页等方法,常用方法如下:

  • 新增:save(T entity)(等同于insert)、saveBatch(Collection entityList)(批量新增);

  • 查询:getById(Serializable id)(等同于selectById)、list()(查询所有)、count()(统计条数);

  • 修改:updateById(T entity)(等同于updateById)、updateBatchById(Collection entityList)(批量修改);

  • 删除:removeById(Serializable id)(等同于deleteById)、removeBatchByIds(Collection<?> idList)(批量删除)。

三、测试验证(两种方式,确保CRUD功能正常)

本文通过「Spring Boot测试类」直接测试CRUD功能,无需编写接口,简单高效;后续也可通过控制层编写接口,用Postman测试(文末附控制层示例)。

1. 测试BaseMapper方式(新手优先)

在test目录下,找到默认的测试类,注入UserMapper,编写测试方法,逐一验证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  // 标记为Spring Boot测试类,启动Spring容器
class CrudDemoApplicationTests {

    // 自动注入UserMapper(Spring扫描@Mapper注解后,自动创建实例)
    @Autowired
    private UserMapper userMapper;

    /**
     * 测试1:新增用户(Create)
     */
    @Test
    void testInsert() {
        // 创建User对象,无需设置id(自增)、createTime、updateTime(自动填充)
        User user = new User();
        user.setName("张三");
        user.setAge(22);
        user.setEmail("zhangsan@163.com");

        // 调用BaseMapper的insert方法,新增数据
        int rows = userMapper.insert(user);
        System.out.println("新增成功,影响行数:" + rows);
        System.out.println("新增用户ID:" + user.getId());  // 新增后,自增ID会自动回显
    }

    /**
     * 测试2:根据ID查询用户(Retrieve)
     */
    @Test
    void testSelectById() {
        // 调用selectById方法,根据ID查询(ID为新增时回显的ID,可修改为自己的)
        User user = userMapper.selectById(1L);
        System.out.println("查询到的用户信息:" + user);
    }

    /**
     * 测试3:查询所有用户 + 条件查询(Retrieve)
     */
    @Test
    void testSelectList() {
        // 1. 查询所有用户(无条件,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);
    }

    /**
     * 测试4:根据ID修改用户(Update)
     */
    @Test
    void testUpdateById() {
        // 1. 先查询要修改的用户(确保用户存在)
        User user = userMapper.selectById(1L);
        // 2. 修改用户信息(仅修改非null字段)
        user.setAge(23);  // 修改年龄
        user.setEmail("zhangsan_update@163.com");  // 修改邮箱

        // 3. 调用updateById方法,修改数据
        int rows = userMapper.updateById(user);
        System.out.println("修改成功,影响行数:" + rows);
    }

    /**
     * 测试5:根据ID删除用户(Delete)
     */
    @Test
    void testDeleteById() {
        // 调用deleteById方法,根据ID删除(ID为要删除的用户ID,谨慎操作)
        int rows = userMapper.deleteById(1L);
        System.out.println("删除成功,影响行数:" + rows);
    }
}

2. 测试IService方式(服务层测试)

注入UserService,测试IService内置的CRUD方法,用法与BaseMapper类似,更贴合实际业务开发。

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 {

    // 自动注入UserService(@Service注解标记,Spring自动管理)
    @Autowired
    private UserService userService;

    // 测试新增
    @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);
    }

    // 测试查询所有
    @Test
    void testList() {
        List<User> userList = userService.list();
        System.out.println("所有用户:" + userList);
    }

    // 测试修改
    @Test
    void testUpdateById() {
        User user = new User();
        user.setId(2L);  // 必须设置ID,否则无法修改
        user.setAge(26);
        boolean success = userService.updateById(user);
        System.out.println("修改是否成功:" + success);
    }

    // 测试删除
    @Test
    void testRemoveById() {
        boolean success = userService.removeById(2L);
        System.out.println("删除是否成功:" + success);
    }

    // 测试批量新增(IService增强方法)
    @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. 测试成功标志

  1. 运行所有测试方法,控制台无红色报错;

  2. SQL日志正常打印(开启了log-impl配置),能看到自动生成的SQL语句;

  3. 打开MySQL客户端,查询user表,能看到新增、修改、删除后的对应数据;

  4. 条件查询、批量操作能返回正确结果。

四、可选扩展:编写控制层接口(Postman测试)

实际开发中,CRUD功能通常通过接口对外提供,这里编写简单的RESTful接口,用Postman测试,贴合真实开发场景。

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数据
 * @RequestMapping:接口统一前缀
 */
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    // 1. 新增用户(POST请求)
    @PostMapping("/add")
    public String addUser(@RequestBody User user) {
        boolean success = userService.save(user);
        return success ? "新增成功" : "新增失败";
    }

    // 2. 根据ID查询用户(GET请求)
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getById(id);
    }

    // 3. 查询所有用户(GET请求)
    @GetMapping("/list")
    public List<User> getUserList() {
        return userService.list();
    }

    // 4. 根据ID修改用户(PUT请求)
    @PutMapping("/update")
    public String updateUser(@RequestBody User user) {
        boolean success = userService.updateById(user);
        return success ? "修改成功" : "修改失败";
    }

    // 5. 根据ID删除用户(DELETE请求)
    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable Long id) {
        boolean success = userService.removeById(id);
        return success ? "删除成功" : "删除失败";
    }

    // 6. 条件查询(示例:根据姓名查询)
    @GetMapping("/list/name")
    public List<User> getUserByName(@RequestParam String name) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name);
        return userService.list(queryWrapper);
    }
}

接口测试方法:启动项目,打开Postman,根据接口请求方式(POST/PUT/GET/DELETE),输入接口地址(如 http://localhost:8081/crud-demo/api/user/add),传递参数,即可测试CRUD功能。

五、高频踩坑点汇总(新手必看,规避90%问题)

整理了新手实现单表CRUD时最常遇到的6个问题,每个问题附上根因和解决方案,遇到报错直接对照排查,快速解决。

踩坑1:Mapper注入失败(No qualifying bean of type ‘xxxMapper’ available)

✅ 报错原因:启动类未添加@MapperScan注解,或注解中的包路径错误;Mapper接口未添加@Mapper注解。

✅ 解决方案:启动类添加@MapperScan(“com.example.cruddemo.mapper”);确保Mapper接口添加@Mapper注解;核对包路径,确保一致。

踩坑2:新增/修改后,时间字段未自动填充

✅ 报错原因:未编写时间自动填充处理器(MyMetaObjectHandler);处理器未添加@Component注解,未被Spring管理;实体类字段的@TableField(fill = …)配置错误。

✅ 解决方案:编写MyMetaObjectHandler类,添加@Component注解;核对实体类字段的fill属性,insert对应INSERT,update对应INSERT_UPDATE。

踩坑3:修改数据无效,无报错

✅ 报错原因:修改时未设置实体类的id字段(MyBatis-Plus根据id修改);实体类所有字段为null,无修改内容;数据库表主键不是id,或主键策略配置错误。

✅ 解决方案:修改时必须设置实体类的id;确保至少有一个非null字段需要修改;核对yml中mybatis-plus.global-config.db-config.id-type配置,与数据库主键策略一致。

踩坑4:条件查询无结果,SQL日志显示条件错误

✅ 报错原因:QueryWrapper构建条件时,字段名与数据库字段不一致;未开启下划线转驼峰配置,导致字段匹配失败(如createTime对应create_time)。

✅ 解决方案:QueryWrapper中使用数据库字段名(如name、age),而非实体类驼峰名;确保yml中开启map-underscore-to-camel-case: true。

踩坑5:Service注入失败(No qualifying bean of type ‘xxxService’ available)

✅ 报错原因:Service实现类未添加@Service注解;Service接口未继承IService,或实现类未继承ServiceImpl。

✅ 解决方案:Service实现类添加@Service注解;确保UserService继承IService,UserServiceImpl继承ServiceImpl<UserMapper, User>。

踩坑6:SQL日志不打印,无法调试

✅ 报错原因:未开启MyBatis-Plus的SQL日志打印配置;log-impl配置路径错误。

✅ 解决方案:在yml的mybatis-plus.configuration中,添加log-impl: org.apache.ibatis.logging.stdout.StdOutImpl。

六、补充:BaseMapper vs IService 选择建议

很多新手会纠结两种方式的选择,结合实际开发场景,给出明确建议,避免选型困惑:

  • 新手入门、简单测试:优先使用BaseMapper,代码更简洁,无需编写Service层,快速实现CRUD;

  • 实际项目开发:优先使用IService+ServiceImpl,封装服务层,便于添加自定义业务逻辑,支持批量操作、分页查询等增强功能,符合分层开发规范(Controller → Service → Mapper);

  • 核心区别:IService基于BaseMapper封装,功能更丰富,返回值更直观(如boolean表示操作结果),适合业务场景;BaseMapper更偏向底层,适合简单场景。

七、总结

Spring Boot + MyBatis-Plus 实现单表CRUD的核心,就是“复用MyBatis-Plus内置接口”,无需编写XML和SQL,极大简化了开发流程,核心步骤可总结为3步:

  1. 准备工作:导入核心依赖、配置数据库连接、创建数据库表;

  2. 核心编码:编写实体类(关联数据库表)、Mapper接口(继承BaseMapper)、Service层(可选,继承IService);

  3. 测试验证:通过测试类或接口,验证新增、查询、修改、删除功能正常。

本文覆盖了新手实现单表CRUD的全流程,从基础配置到进阶用法,从测试验证到踩坑排查,贴合实战场景,新手只需跟着步骤操作,就能快速上手。后续可基于此基础,学习MyBatis-Plus的高级特性(条件构造器、分页插件、自动生成代码),进一步提高开发效率。

若遇到其他问题,可对照本文踩坑点排查,或留言交流,助力你快速搞定单表CRUD开发!

Spring Boot 整合 MyBatis Plus:快速构建高效持久层 摘要: MyBatis-Plus作为MyBatis的增强工具,通过简化CRUD操作显著提升Java后端开发效率。文章详细介绍了Spring Boot整合MyBatis-Plus的步骤:1)引入依赖配置数据源;2)使用注解简化实体类与Mapper接口(继承BaseMapper即可获得基础CRUD能力);3)演示Service层调用示例。核心优势包括无侵入集成、自动生成代码、内置分页/乐观锁等功能,有效减少冗余代码,尤其适合单表操作频繁的场景。通过5分钟快速配置,开发者可专注业务逻辑而非重复的持久层编写。 阅读详情

相关推荐

【SpringBoot3】Spring Boot 3.0 集成 Mybatis Plus

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

m0_74824517的博客 2421

MyBatis-plus最详细的入门使用教程

(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发提高效率而生它具有什么特性呢?我们为什么要使用它呢?无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求支持 Lambda 形式调用。

2301_81365242的博客 921

Spring Boot整合MyBatis-Plus实现高效CRUD开发

ORM框架是Java开发中处理数据库操作的核心组件,MyBatis作为主流选择以其灵活性著称。MyBatis-Plus在MyBatis基础上进行了增强,通过自动化CRUD操作和条件构造器等功能,显著提升开发效率。结合Spring Boot的自动化配置特性,开发者可以快速构建高性能数据访问层。这种组合特别适合需要快速迭代的业务系统,能减少60%以上的样板代码。在实际工程中,MyBatis-Plus的条件构造器和分页插件等特性,为处理用户管理、订单系统等常见业务场景提供了标准化解决方案。

cigang4063的博客 389

MyBatis-Plus 入门到实战,极简实现单表 CRUD

通过本文的讲解,我们了解了 MyBatis-Plus 的核心特性和适用场景,并通过 5 个简单步骤完成了 MP 在 Spring Boot 项目中的集成,实现了单表的查询操作。MyBatis-Plus 是 MyBatis 的增强工具,无侵入、低损耗,专注于简化单表 CRUD 开发;只需继承,即可自动拥有全量单表 CRUD 方法,无需手写 SQL;通过配置日志可以查看 MP 自动生成的 SQL,方便开发调试;使用@TableName和注解可快速解决实体类与数据库表 / 字段不一致的问题。

2301_82132279的博客 502

SpringBoot快速教程四整合Mybatis-plus

SpringBoot3版本整合最新版Mybatis-plus的教程方便自己日常无缝迁移,那么来了,本篇教程就是基于SpringBoot3.3.4整合最新版的Mybatis-plus的3.5.7的SpringBoot3专属版本,希望大家可以和之前的Mybatis做一下对比,俗话说,没有对比,就没有伤害!

程序员Feri 1665

Spring Boot框架集成Mybatis-plus

国产的开源框架,基于mybatis,相当于对mybatis进行了二次的封装,是2019年开源中国里面排行第一的框架,它的核心功能就是简化mybatis开发,提高效率。官网:(https://mp.baomidou.com/)依赖的官网:(https://mvnrepository.com/)

小白的博客 2031

Mybatis-plus教程

mybatis-plus学习笔记

m0_59855153的博客 419

Mybatis-Plus 实战:Spring Boot 中高效 CRUD 与进阶技巧

在 Java 后端开发中,ORM 框架是连接应用与数据库的核心组件,其核心原理是通过对象关系映射将数据库操作抽象为面向对象的方法调用。MyBatis 作为一款流行的半自动化 ORM 框架,以其灵活性和对 SQL 的直接控制能力而备受青睐。然而,在涉及大量基础数据操作的场景中,手动编写重复的 CRUD(增删改查)SQL 语句会显著降低开发效率。Mybatis-Plus 正是在此背景下应运而生的增强工具包,它在保留 MyBatis 所有特性的基础上,通过内置通用 Mapper、强大的条件构造器等功能,实现了基础

weixin_30699955的博客 419

MyBatis Plus:快速上手指南

本文旨在帮助后端开发者快速上手 MyBatis Plus,覆盖 BaseMapper 内置 CRUD、Wrapper条件构造、分页、自动填充、逻辑删除等核心功能,并结合实际踩坑经验说明 MP 的适用边界。

weixin_68431870的博客 464

MyBatis与MyBatis-Plus实战指南

本文是一份MyBatis与MyBatis-Plus的完整开发指南,主要涵盖以下内容: 框架对比:MyBatis提供灵活SQL映射能力,适合复杂查询;MyBatis-Plus作为增强工具,简化单表CRUD操作,提高开发效率。 核心功能详解: MyBatis基础:配置、Mapper接口、动态SQL、结果映射 MyBatis-Plus特性:通用Mapper/Service、条件构造器、代码生成器、主键策略 高级特性:分页插件、乐观锁、逻辑删除、动态表名、枚举处理等 整合实践:与SpringBoot的集成方式及事务

索大神的博客 1533

Spring Boot整合MyBatis-Plus快速开发实战

MyBatis-Plus 是在 MyBatis 基础上封装的增强框架,旨在简化数据库操作、提升开发效率。它不仅保留了 MyBatis 的灵活性,还通过自动化手段减少了重复性代码的编写。Spring Boot项目遵循标准的Maven项目结构,具有清晰的分层目录,便于模块化开发与维护。典型的Spring Boot项目结构如下:src/├── main/│ │└── test/└── java/:Spring Boot项目的主类,包含main()方法,用于启动应用。

weixin_33562004的博客 1005

RuoYi-Vue-Plus 多租户后台管理系统:把数据隔离做进框架,把交付周期压到三周

**选型现场的三个困境**。第一,客户要 SaaS 后台,租户隔离、角色权限、审批流、对象存储一个都不能少,自研基础能力就要 2-3 个月。第二,选了老牌单体框架,改造到一半发现权限体系扩展性差、缓存不支持集群、多数据源要手写配置,改造成本比自研还高。第三,多租户靠开发人员自觉拼 `tenant_id`,一个查询漏条件,A 租户就能看到 B 租户的数据,这属于安全事故。三个问题指向同一个结论:**

gitblog_00286的博客 896

ESP-IDF 利用ESP32构建智能音乐播放器(一)---------- 实现SD卡MP3文件的解码与播放

本文详细介绍了如何利用ESP32和ESP-IDF开发框架,从零开始构建一个智能音乐播放器。文章重点讲解了如何通过SD卡模块读取MP3文件,并集成Helix MP3解码库进行软件解码,最终通过I2S接口驱动音频模块实现播放。内容涵盖硬件连接、软件环境搭建、核心解码与输出逻辑,为嵌入式音频开发提供了完整的实战指南。

weixin_29163797的博客 234

MyBatis-Plus 从入门到实战:高效简化数据库开发的完整指南

(简称 MP)是 MyBatis 的增强工具,由国人开发维护,在 MyBatis 的基础之上只做增强、不做改变。只为简化开发而生,不对 MyBatis 原有能力做任何侵入式改动。简化单表 CRUD:传统 MyBatis 中,即使是最简单的单表查询也需要手写 XML 映射文件或注解 SQL,而 MP 内置的BaseMapper直接提供了数十种常用方法,绝大多数单表操作可以做到零 SQL 编写。提升开发效率。

suger__salt的博客 657

数据分析项目:直播电商用户流失分析

其中,'Tenure'(在网时长)可能是影响用户流失的关键因素,意味着用户在平台上的停留时间越长,流失的可能性可能越低,这提示平台应注重提高用户粘性,增加用户在平台上的活跃度和停留时间。)的分析,挖掘用户流失的原因和模式,分析发现用户投诉处理效率(Complain)、距上次消费时长(DaySinceLastOrder)、会员生命周期(Tenure)等8项核心指标对流失预测贡献度达87%,模型准确率94.58%,并提出相应的建议。重视用户的满意度,及时处理用户的投诉和反馈,不断改进平台的服务和功能。

Nervousr的博客 2457

ARM 汇编指令:LSL(逻辑左移) 和 LSR(逻辑右移)

ARM 汇编中的 LSL(逻辑左移)和 LSR(逻辑右移)是基础移位指令,分别实现二进制位的左移和右移操作。LSL 低位补0,等效于乘以2^n;LSR 高位补0,等效于无符号除以2^n。这两个指令可以单独使用或与其他指令结合(如ADD、MOV等),利用ARM的"桶形移位器"硬件实现高效运算。关键特性包括:移位范围0-31(LSL)或1-32(LSR),可选更新标志位,以及与其他指令结合时的无额外开销优势。LSR与ASR(算术右移)的主要区别在于高位填充方式,分别适用于无符号和有符号数处理

guigenyi的专栏 1809

Spring Boot+MyBatis-Plus实战:搭建线下活动报名签到系统

在Web应用开发中,快速搭建可用的业务系统是后端工程师的普遍需求。Spring Boot作为Java领域主流的微服务开发框架,凭借自动配置和内置容器,能显著降低项目初始化成本;MyBatis-Plus进一步简化了单表CRUD操作,让开发者无需编写繁琐的XML映射即可完成数据持久化。这类轻量级技术组合非常适合生命周期短、并发量有限的活动类应用。以线下活动报名签到系统为例,从数据库设计、后端接口、前端页面到部署上线,Spring Boot配合MySQL可以高效实现活动报名、现场签到、数据统计等核心功能,同时通过

weixin_30587927的博客 385

PICO4 VR开发调试神器:用Live Preview Plugin实现电脑串流,告别反复打包烧录的繁琐流程

本文详细介绍了PICO4 VR开发中如何使用Live Preview Plugin实现电脑串流,显著提升开发效率。通过实时预览和调试功能,开发者可以避免反复打包烧录的繁琐流程,特别适用于Unity环境下的VR应用开发。文章涵盖环境配置、连接设置、实时调试技巧及性能优化方案,是PICO4开发者的必备指南。

weixin_34110970的博客 418

Spring Boot开发团队财务管理系统Procura完整实录

团队财务管理的核心痛点在于多人共用账本、收支归属混乱、预算超支难以及时预警。Spring Boot作为Java主流的微服务开发框架,凭借自动配置和丰富的生态,能够快速构建企业级Web应用;结合Spring Security与JWT实现无状态登录认证,可以保障接口安全。MyBatis Plus则进一步简化了单表CRUD与数据持久化流程,让开发者更专注于业务逻辑。基于这套技术栈,面向小团队场景的财务管理系统可从数据库设计、角色权限、收支记录、预算预警到报表统计逐步落地,兼具工程实践价值与二次改造空间。本文以代号

weixin_33804582的博客 526

混合精度训练与推理:平衡性能与效率

在深度学习领域,模型的训练和推理通常需要大量的计算资源和时间。随着模型规模的不断增大,如大型语言模型、复杂的视觉模型等,对计算资源的需求也呈指数级增长。混合精度训练与推理技术应运而生,它通过在训练和推理过程中同时使用不同精度的数据类型,在保证模型性能的前提下,显著提高计算效率,减少内存占用。本文的目的是全面介绍混合精度训练与推理技术,包括其原理、实现方法、应用场景以及相关工具和资源,帮助读者深入理解并掌握该技术,从而在实际项目中更好地平衡性能与效率。

操作系统内核探秘的博客 1068

Google Earth Engine(GEE)——使用归一化燃烧指数 (NBR) 绘制地表烧伤严重程度图

归一化燃烧指数(Normalized Burn Ratio, NBR)是一种遥感指标,用于评估野火或烧伤地面后的植被恢复情况。NBR能增强较大范围的火灾区域,如大于200公顷。它是通过比较远红外波段 (SWIR) 和近红外波段 (NIR) 的反射率来计算的。SWIR波段测量烧伤地面的反射率,NIR波段测量没有受到烧伤影响的植被的反射率。NBR的计算公式为:NBR =(NIR-SWIR)/(NIR + SWIR)。其中,NIR为近红外波段,SWIR为短波红外波段。

此星光明博客 3464

mybatis-plus快速搭建

分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)MybatisPlus提供了starter,实现了自动Mybatis以及MybatisPlus的自动装配功能,由于这个starter包含对mybatis的自动装配,因此完全可以替换掉Mybatis的starter。

Lance_369的博客 1691

深度解析:Android开发工程师(嵌入式系统方向)职位 - 技术需求、面试准备与发展路径

本文深入分析了嵌入式Android开发工程师的岗位要求和技术内涵。该职位需要掌握C/C++、Linux系统编程、硬件接口等核心技术,能够进行Android系统底层定制开发,包括HAL层实现、Framework修改、性能优化等工作。文章详细解读了岗位职责,梳理了必备技术栈,提供了针对性的面试问题与参考答案,并探讨了职业发展路径。这类岗位要求开发者兼具软件工程能力和硬件基础知识,适合在智能电视、机顶盒、车载系统等嵌入式领域发展的技术人员。

郑伟强dev的专栏 132

Spring-boot集成mybatis-plus及mybatis-plus多表联查,分页查询

Spring-boot集成mybatis-plus及mybatis-plus多表联查,分页查询(拒绝写sql语句)

LoveTalk的博客 3536

手把手教你学Simulink——基于Simulink的储能PCS(功率转换系统)离网V/f控制仿真示例

本文带你从零开始,在Simulink中硬核还原了一套完整的100kW 储能PCS离网V/f控制系统。通过引入:✅无PLL的自主角度生成机制(实现真正的“构网”能力)✅电压外环与电流内环的双闭环解耦架构(兼顾稳态精度与动态响应)✅黑启动软充电与有源阻尼等工程化手段(确保系统平滑建压与抗谐振)核心收获透彻理解了储能系统在无大电网支撑下的自主运行机理。掌握了从“跟网(Grid-Following)”向“构网(Grid-Forming)”跨越的控制算法核心差异。

MHD0815的博客 76

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

上一篇: Spring Boot + MyBatis-Plus 快速连接 MySQL
下一篇: Spring Boot 统一返回格式 + 全局异常处理(实战版)
码客日记
博客等级 码龄6年 149粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码客日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值