SpringBoot整合MyBatis-Plus:零XML实现高效CRUD

news2025/5/14 6:41:09

前言

作为一名开发者,数据库操作是我们日常工作中不可或缺的部分。传统的MyBatis虽然强大,但需要编写大量XML映射文件,这在快速开发的今天显得效率不足。MyBatis-Plus(简称MP)作为MyBatis的增强工具,在保留MyBatis所有特性的基础上,极大地简化了开发流程。本文将带你全面了解如何在SpringBoot项目中整合MyBatis-Plus,实现零XML配置的高效CRUD操作。

一、MyBatis-Plus简介:JPA vs MyBatis vs MyBatis-Plus

在开始整合之前,我们先了解下这三种持久层框架的特点和差异:

特性JPAMyBatisMyBatis-Plus
ORM支持全自动ORM半自动ORMMyBatis增强
SQL控制自动生成,可控性低完全手动控制自动生成+手动控制
XML配置需要大量XML零XML
CRUD操作方法命名自动生成需手动编写内置通用Mapper
学习曲线中等较高低(MyBatis基础上)
适用场景简单标准业务复杂SQL业务各种业务场景

MyBatis-Plus的核心优势

  1. 无侵入:只做增强不做改变,引入它不会对现有工程产生影响

  2. 损耗小:启动即会自动注入基本CRUD,性能基本无损耗

  3. 强大CRUD:内置通用Mapper、通用Service,少量配置即可实现单表大部分CRUD操作

  4. 多种插件:支持分页、性能分析、乐观锁、逻辑删除等

二、SpringBoot整合MyBatis-Plus

1. 添加依赖

首先在pom.xml中添加必要依赖:

<!-- SpringBoot Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- MyBatis-Plus Starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

<!-- 数据库驱动(以MySQL为例) -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- Lombok简化实体类开发 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2. 配置数据库连接

application.yml中配置数据源和MyBatis-Plus相关配置:

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

mybatis-plus:
  configuration:
    # 下划线转驼峰
    map-underscore-to-camel-case: true
    # 日志实现
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      # 主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID", UUID:"全局唯一UUID"
      id-type: auto
      # 逻辑删除字段名
      logic-delete-field: deleted
      # 逻辑删除值
      logic-delete-value: 1
      # 逻辑未删除值
      logic-not-delete-value: 0

三、实体类注解详解

MyBatis-Plus通过注解简化了实体类与数据库表的映射关系:

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

import java.util.Date;

@Data
@TableName("t_user")  // 指定表名,省略时默认使用类名作为表名
public class User {
    
    @TableId(type = IdType.AUTO)  // 主键自增
    private Long id;
    
    private String username;
    
    private String password;
    
    @TableField("real_name")  // 指定数据库字段名
    private String realName;
    
    private Integer age;
    
    private String email;
    
    @TableField(fill = FieldFill.INSERT)  // 插入时自动填充
    private Date createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)  // 插入和更新时自动填充
    private Date updateTime;
    
    @Version  // 乐观锁版本字段
    private Integer version;
    
    @TableLogic  // 逻辑删除字段
    private Integer deleted;
}

常用注解说明

  • @TableName:指定实体类对应的表名

  • @TableId:指定主键字段,可配置主键生成策略

  • @TableField:指定非主键字段与数据库列的映射关系

  • @Version:乐观锁注解

  • @TableLogic:逻辑删除注解

四、Mapper接口与Service层开发

1. 创建Mapper接口

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;

public interface UserMapper extends BaseMapper<User> {
    // 继承BaseMapper后已包含基本CRUD方法
    // 可在此添加自定义SQL方法
}

2. Service层实现

MyBatis-Plus提供了通用的Service接口:

public interface UserService extends IService<User> {
    // 可扩展自定义方法
}

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 实现类只需继承ServiceImpl即可
}

3. 基础CRUD示例

@RestController
@RequestMapping("/user")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // 新增
    @PostMapping
    public boolean save(@RequestBody User user) {
        return userService.save(user);
    }
    
    // 删除
    @DeleteMapping("/{id}")
    public boolean remove(@PathVariable Long id) {
        return userService.removeById(id);
    }
    
    // 修改
    @PutMapping
    public boolean update(@RequestBody User user) {
        return userService.updateById(user);
    }
    
    // 查询单个
    @GetMapping("/{id}")
    public User getById(@PathVariable Long id) {
        return userService.getById(id);
    }
    
    // 分页查询
    @GetMapping("/page")
    public IPage<User> page(@RequestParam(defaultValue = "1") Integer current,
                           @RequestParam(defaultValue = "10") Integer size) {
        return userService.page(new Page<>(current, size));
    }
}

五、高级功能实战

1. 分页插件配置

MyBatis-Plus的分页功能需要先配置分页插件:

@Configuration
public class MyBatisPlusConfig {
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

使用示例:

// 基本分页
Page<User> page = new Page<>(1, 10);  // 当前页,每页大小
userMapper.selectPage(page, null);

// 自定义SQL分页
@Select("SELECT * FROM t_user WHERE age > #{age}")
IPage<User> selectPageByAge(IPage<User> page, @Param("age") Integer age);

2. 自动填充功能

实现MetaObjectHandler接口来处理自动填充字段:

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }
    
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

3. 条件构造器Wrapper

MyBatis-Plus提供了强大的条件构造器,可以构建复杂查询条件:

// 查询年龄大于18且名字包含"张"的用户
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 18)
       .like(User::getUsername, "张");
List<User> users = userMapper.selectList(wrapper);

// 更新操作
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(User::getUsername, "张三")
             .set(User::getAge, 25);
userMapper.update(null, updateWrapper);

4. 逻辑删除配置

application.yml中已经配置了逻辑删除,实体类字段添加@TableLogic注解后,删除操作将自动变为更新操作:

// 实际执行的是UPDATE t_user SET deleted=1 WHERE id=? AND deleted=0
userMapper.deleteById(1L);

// 查询时会自动加上WHERE deleted=0条件
userMapper.selectList(null);

5. 乐观锁实现

乐观锁通过版本号机制实现:

  1. 实体类添加@Version注解

  2. 配置乐观锁插件:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    // 乐观锁插件
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

 使用示例:

// 先查询获取version
User user = userMapper.selectById(1L);
// 修改数据
user.setUsername("new name");
// 执行更新,会带上version条件
userMapper.updateById(user);

六、性能优化建议

  1. 批量操作:使用saveBatchupdateBatchById等方法提高批量操作效率

  2. SQL打印:开发环境可开启SQL打印方便调试,生产环境应关闭

  3. 索引优化:为常用查询条件添加数据库索引

  4. 查询字段控制:避免使用select *,明确指定查询字段

  5. 逻辑删除:对于大表,逻辑删除可能影响性能,需考虑归档策略

七、常见问题解决方案

  1. 表名/字段名不一致

    • 使用@TableName@TableField注解明确指定

    • 配置全局的下划线转驼峰命名

  2. 主键策略问题

    • IdType.AUTO:数据库自增

    • IdType.ASSIGN_ID:雪花算法生成ID(默认)

    • IdType.ASSIGN_UUID:UUID生成

  3. 分页失效

    • 确保配置了分页插件

    • 检查Page参数是否正确传递

  4. 逻辑删除无效

    • 检查application.yml中的逻辑删除配置

    • 确保实体类字段添加了@TableLogic注解

结语

通过本文的介绍,相信你已经掌握了SpringBoot整合MyBatis-Plus的核心要点。MyBatis-Plus的强大功能可以让我们从繁琐的XML配置中解放出来,专注于业务逻辑的实现。在实际项目中,你可以根据需求组合使用各种功能,如分页+条件查询、逻辑删除+自动填充等,构建出高效可靠的数据访问层。

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

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

相关文章

python酒店健身俱乐部管理系统

目录 技术栈介绍具体实现截图系统设计研究方法&#xff1a;设计步骤设计流程核心代码部分展示研究方法详细视频演示试验方案论文大纲源码获取/详细视频演示 技术栈介绍 Django-SpringBoot-php-Node.js-flask 本课题的研究方法和研究步骤基本合理&#xff0c;难度适中&#xf…

嵌入式开发学习(第二阶段 C语言基础)

综合案例《猜拳游戏》 需求&#xff1a; 本游戏是一款单机游戏&#xff0c;人机交互 规则&#xff1a; 需要双方出拳&#xff1a;石头、剪刀、布赢&#xff1a; 石头→剪刀剪刀→ 布布 →石头 两边出拳相等输&#xff1a; … 实现&#xff1a; 选择对手玩家出拳对手出拳判断胜…

YOLOv1:开启实时目标检测的新篇章

YOLOv1&#xff1a;开启实时目标检测的新篇章 在深度学习目标检测领域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列算法无疑占据着重要地位。其中&#xff0c;YOLOv1作为开山之作&#xff0c;以其独特的设计理念和高效的检测速度&#xff0c;为后续的目标…

FFmpeg多路节目流复用为一路包含多个节目的输出流

在音视频处理领域&#xff0c;将多个独立的节目流&#xff08;如不同频道的音视频内容&#xff09;合并为一个包含多个节目的输出流是常见需求。FFmpeg 作为功能强大的多媒体处理工具&#xff0c;提供了灵活的流复用能力&#xff0c;本文将通过具体案例解析如何使用 FFmpeg 实现…

分子动力学模拟揭示点突变对 hCFTR NBD1结构域热稳定性的影响

囊性纤维化&#xff08;CF&#xff09; 作为一种严重的常染色体隐性遗传疾病&#xff0c;全球约有 10 万名患者深受其害。它会累及人体多个器官&#xff0c;如肺部、胰腺等&#xff0c;严重影响患者的生活质量和寿命。CF 的 “罪魁祸首” 是 CFTR 氯离子通道的突变&#xff0c;…

关于SIS/DCS点检周期

在中国化工行业&#xff0c;近几年在设备维护上有个挺有意思的现象&#xff0c;即SIS和DCS这两个系统的点检周期问题&#xff0c;隔三差五就被管理层会议讨论&#xff0c;可以说是企业管理层关注的重要方向与关心要素。 与一般工业行业中设备运维不同&#xff0c;SIS与DCS的点…

【PmHub后端篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现

1 限流的重要性 在高并发系统中&#xff0c;保护系统稳定运行的关键技术有缓存、降级和限流。 缓存通过在内存中存储常用数据&#xff0c;减少对数据库的访问&#xff0c;提升系统响应速度&#xff0c;如浏览器缓存、CDN缓存等多种应用层面。降级则是在系统压力过大或部分服务…

CST软件仿真案例——太阳能薄膜频谱吸收率

CST软件中的太阳能薄膜的功率吸收可用光频电磁波在介质材料中的损耗来计算。本案例计算非晶硅的功率吸收&#xff0c;然后考虑真实太阳频谱&#xff0c;计算有效吸收频谱。 用太阳能单元模板&#xff0c;时域求解器&#xff1a; 材料库提取四个材料&#xff0c;非晶硅&#xf…

ABAP+旧数据接管的会计年度未确定

导资产主数据时&#xff0c;报错旧数据接管的会计年度未确定 是因为程序里面使用了下列函数AISCO_CALCULATE_FIRST_DAY&#xff0c;输入公司代码&#xff0c;获取会计年度&#xff0c;这个数据是在后台表T093C表中取数的&#xff0c;通过SE16N可以看到后台表数据没有数&#xf…

养生:打造健康生活的全方位策略

在生活节奏不断加快的当下&#xff0c;养生已成为提升生活质量、维护身心平衡的重要方式。从饮食、运动到睡眠&#xff0c;再到心态调节&#xff0c;各个方面的养生之道共同构建起健康生活的坚实基础。以下为您详细介绍养生的关键要点&#xff0c;助您拥抱健康生活。 饮食养生…

贪吃蛇游戏排行榜模块开发总结:从数据到视觉的实现

一、项目背景与成果概览 在完成贪吃蛇游戏核心玩法后,本次开发重点聚焦于排行榜系统的实现。该系统具备以下核心特性: 🌐 双数据源支持:本地存储(localStorage)与远程API自由切换 🕒 时间维度统计:日榜/周榜/月榜/全时段数据筛选 🎮 模式区分:闯关模式(关卡进度…

屏幕与触摸调试

本章配套视频介绍: 《28-屏幕与触摸设置》 【鲁班猫】28-屏幕与触摸设置_哔哩哔哩_bilibili LubanCat-RK3588系列板卡都支持mipi屏以及hdmi显示屏的显示。 19.1. 旋转触摸屏 参考文章 触摸校准 参考文章 旋转触摸方向 配置触摸旋转方向 1 2 # 1.查看触摸输入设备 xinput…

使用 百度云大模型平台 做 【提示词优化】

1. 百度云大模型平台 百度智能云千帆大模型平台 &#xfeff; 平台功能&#xff1a;演示了阿里云大模型的百炼平台&#xff0c;该平台提供Prompt工程功能&#xff0c;支持在线创建和优化Prompt模板模板类型&#xff1a;平台提供多种预制模板&#xff0c;同时也支持用户自定义…

IJCAI 2025 | 高德首个原生3D生成基座大模型「G3PT」重塑3D生成的未来

国际人工智能联合会议&#xff08;IJCAI&#xff09;是人工智能领域最古老、最具权威性的学术会议之一&#xff0c;自1969年首次举办以来&#xff0c;至今已有近六十年的历史。它见证了人工智能从萌芽到蓬勃发展的全过程&#xff0c;是全球人工智能研究者、学者、工程师和行业专…

Samtec助力电视广播行业

【摘要前言】 现代广播电视技术最有趣的方面之一就是界限的模糊。过去&#xff0c;音频和视频是通过射频电缆传输的模拟技术采集的&#xff0c;而现在&#xff0c;数字世界已经取代了模拟技术。物理胶片和磁带已让位于数字存储设备和流媒体。 在这个过程中&#xff0c;连接器…

密码学--仿射密码

一、实验目的 1、通过实现简单的古典密码算法&#xff0c;理解密码学的相关概念 2、理解明文、密文、加密密钥、解密密钥、加密算法、解密算法、流密码与分组密码等。 二、实验内容 1、题目内容描述 ①随机生成加密密钥&#xff0c;并验证密钥的可行性 ②从plain文件读入待…

SpringBoot整合MQTT实战:基于EMQX实现双向设备通信(附源码)

简言&#xff1a; 在万物互联的时代&#xff0c;MQTT协议凭借其轻量级、高效率的特性&#xff0c;已成为物联网通信的事实标准。本教程将带领您在Ubuntu系统上搭建EMQX 5.9.0消息服务器&#xff0c;并使用Spring Boot快速实现两个客户端的高效通信。通过本指南&#xff0c;您将…

从零开始掌握FreeRTOS(2)链表之节点的定义

目录 节点 节点定义 节点实现 根节点 根节点定义 精简节点定义 根节点实现 在上篇文章,我们完成了 FreeRTOS 的移植。在创建任务之前,我们需要先了解FreeRTOS的运转机制。 FreeRTOS是一个多任务系统,由操作系统来管理执行每个任务。这些任务全都挂载到一个双向循…

【数据结构】——双向链表

一、链表的分类 我们前面学习了单链表&#xff0c;其是我们链表中的其中一种&#xff0c;我们前面的单链表其实全称是单向无头不循环链表&#xff0c;我们的链表从三个维度进行分类&#xff0c;一共分为八种。 1、单向和双向 可以看到第一个链表&#xff0c;其只能找到其后一个…

mybatis中${}和#{}的区别

先测试&#xff0c;再说结论 userService.selectStudentByClssIds(10000, "wzh or 11");List<StudentEntity> selectStudentByClssIds(Param("stuId") int stuId, Param("field") String field);<select id"selectStudentByClssI…