MyBatis-Plus基础篇详解

文章目录

  • 前言
  • 一、简单介绍MyBatis-Plus
    • [1.1 特性](#1.1 特性)
    • [1.2 架构](#1.2 架构)
  • 二、SpringBoot集成MyBatis-Plus
    • [2.1 项目搭建](#2.1 项目搭建)
    • [2.2 导入所需依赖](#2.2 导入所需依赖)
    • [2.3 配置application.yml](#2.3 配置application.yml)
    • [2.4 创建实体类](#2.4 创建实体类)
    • [2.5 创建Mapper接口](#2.5 创建Mapper接口)
    • [2.6 启动类配置](#2.6 启动类配置)
  • 三、DQL操作
    • [3.1 基础查询](#3.1 基础查询)
    • [3.2 QueryWrapper查询](#3.2 QueryWrapper查询)
    • [3.3 LambdaQueryWrapper查询](#3.3 LambdaQueryWrapper查询)
    • [3.4 分页查询](#3.4 分页查询)
  • 四、DML操作
    • [4.1 添加操作](#4.1 添加操作)
    • [4.2 修改操作](#4.2 修改操作)
    • [4.3 删除操作](#4.3 删除操作)
  • 总结

前言

作为刚接触这款工具的小白,可以先到Mybatis-Plus官网,跟着文档熟悉具体的方法并手动跟着敲一遍,这样更容易理解掌握这项技术。

一、简单介绍MyBatis-Plus

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

1.1 特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence)
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询

1.2 架构

MyBatis-Plus基于MyBatis进行开发,MyBatis-Plus启动注入了默认实现,对原生MyBatis的使用没有任何影响。

二、SpringBoot集成MyBatis-Plus

2.1 项目搭建

新建一个SpringBoot 项目并选择用Maven 来管理依赖:

2.2 导入所需依赖

新建好项目后,导入以下依赖:

xml 复制代码
	<dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.9</version>
        </dependency>
    </dependencies>

2.3 配置application.yml

yaml 复制代码
server:
  port: 8080

# 数据源
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource

# mybatis-plus配置
mybatis-plus:
  type-aliases-package: com.coldscholor.pojo
  mapper-locations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# 日志
logging:
  level:
    com.coldscholor: debug
  pattern:
    date-format: yyyy-MM-dd HH:mm:ss

2.4 创建实体类

java 复制代码
@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    @TableField(value = "name")
    private String name;
    private Integer age;
    private String email;
    private String password;
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    
    @TableLogic
    private Integer deleted;
}

2.5 创建Mapper接口

java 复制代码
public interface UserMapper extends BaseMapper<User> {
    // 继承BaseMapper后,无需编写mapper.xml文件,即可获得CRUD功能
}

2.6 启动类配置

java 复制代码
@SpringBootApplication
@MapperScan("com.coldscholor.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

三、DQL操作

MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。

3.1 基础查询

java 复制代码
@Test
public void testSelect() {
    // 查询所有用户
    List<User> userList = userMapper.selectList(null);
    userList.forEach(System.out::println);
    
    // 根据id查询
    User user = userMapper.selectById(1L);
    System.out.println(user);
    
    // 根据id批量查询
    List<Long> idList = Arrays.asList(1L, 2L, 3L);
    List<User> users = userMapper.selectBatchIds(idList);
    users.forEach(System.out::println);
    
    // 根据map条件查询
    Map<String, Object> map = new HashMap<>();
    map.put("name", "Tom");
    map.put("age", 20);
    List<User> userList2 = userMapper.selectByMap(map);
    userList2.forEach(System.out::println);
}

3.2 QueryWrapper查询

java 复制代码
@Test
public void testQueryWrapper() {
    // 方式一:按条件查询
    QueryWrapper<User> qw = new QueryWrapper<>();
    qw.lt("age", 18);
    List<User> userList = userMapper.selectList(qw);
    System.out.println(userList);
    
    // 方式二:lambda格式按条件查询
    QueryWrapper<User> qw2 = new QueryWrapper<>();
    qw2.lambda().lt(User::getAge, 10);
    List<User> userList2 = userMapper.selectList(qw2);
    System.out.println(userList2);
    
    // 组合条件查询
    QueryWrapper<User> qw3 = new QueryWrapper<>();
    qw3.like("name", "o").between("age", 20, 30);
    List<User> userList3 = userMapper.selectList(qw3);
    System.out.println(userList3);
}

3.3 LambdaQueryWrapper查询

java 复制代码
@Test
public void testLambdaQueryWrapper() {
    // 方式三:lambda格式按条件查询
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    lqw.lt(User::getAge, 10);
    List<User> userList = userMapper.selectList(lqw);
    System.out.println(userList);
    
    // 并且与或者关系
    LambdaQueryWrapper<User> lqw2 = new LambdaQueryWrapper<>();
    // 并且关系:10到30岁之间
    lqw2.lt(User::getAge, 30).gt(User::getAge, 10);
    // 或者关系:小于10岁或者大于30岁
    // lqw2.lt(User::getAge, 10).or().gt(User::getAge, 30);
    List<User> userList2 = userMapper.selectList(lqw2);
    System.out.println(userList2);
    
    // 条件查询
    LambdaQueryWrapper<User> lqw3 = new LambdaQueryWrapper<>();
    // 等同于=
    lqw3.eq(User::getName, "Jerry").eq(User::getPassword, "jerry123");
    User user = userMapper.selectOne(lqw3);
    System.out.println(user);
    
    // 范围查询
    LambdaQueryWrapper<User> lqw4 = new LambdaQueryWrapper<>();
    lqw4.between(User::getAge, 18, 30);
    List<User> userList4 = userMapper.selectList(lqw4);
    System.out.println(userList4);
    
    // 模糊查询
    LambdaQueryWrapper<User> lqw5 = new LambdaQueryWrapper<>();
    lqw5.like(User::getName, "Tom").likeLeft(User::getEmail, "qq.com");
    List<User> userList5 = userMapper.selectList(lqw5);
    System.out.println(userList5);
    
    // 排序
    LambdaQueryWrapper<User> lqw6 = new LambdaQueryWrapper<>();
    lqw6.orderByDesc(User::getAge).orderByAsc(User::getId);
    List<User> userList6 = userMapper.selectList(lqw6);
    System.out.println(userList6);
}

3.4 分页查询

  1. 配置分页插件:
java 复制代码
@Configuration
public class MybatisPlusConfig {
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}
  1. 分页查询测试:
java 复制代码
@Test
public void testPage() {
    // 创建分页对象,参数1:当前页,参数2:每页记录数
    Page<User> page = new Page<>(1, 3);
    
    // 条件分页查询
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    lqw.ge(User::getAge, 20);
    
    Page<User> userPage = userMapper.selectPage(page, lqw);
    
    System.out.println("总记录数:" + userPage.getTotal());
    System.out.println("总页数:" + userPage.getPages());
    System.out.println("当前页:" + userPage.getCurrent());
    System.out.println("每页记录数:" + userPage.getSize());
    
    List<User> records = userPage.getRecords();
    records.forEach(System.out::println);
}

四、DML操作

4.1 添加操作

java 复制代码
@Test
public void testInsert() {
    User user = new User();
    user.setName("张三");
    user.setAge(25);
    user.setEmail("zhangsan@example.com");
    user.setPassword("123456");
    
    int result = userMapper.insert(user);
    System.out.println("影响行数:" + result);
    System.out.println("用户ID:" + user.getId()); // 主键回填
}

@Test
public void testInsertBatch() {
    List<User> userList = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        User user = new User();
        user.setName("用户" + i);
        user.setAge(20 + i);
        user.setEmail("user" + i + "@example.com");
        userList.add(user);
    }
    
    // 批量插入
    userService.saveBatch(userList);
}

4.2 修改操作

java 复制代码
@Test
public void testUpdate() {
    // 根据id修改
    User user = new User();
    user.setId(1L);
    user.setName("李四");
    user.setAge(30);
    
    int result = userMapper.updateById(user);
    System.out.println("影响行数:" + result);
    
    // 条件修改
    User user2 = new User();
    user2.setAge(25);
    
    LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
    luw.eq(User::getName, "Tom").set(User::getAge, 25);
    
    int result2 = userMapper.update(user2, luw);
    System.out.println("影响行数:" + result2);
}

4.3 删除操作

java 复制代码
@Test
public void testDelete() {
    // 根据id删除
    int result = userMapper.deleteById(1L);
    System.out.println("影响行数:" + result);
    
    // 批量删除
    List<Long> idList = Arrays.asList(2L, 3L, 4L);
    int result2 = userMapper.deleteBatchIds(idList);
    System.out.println("影响行数:" + result2);
    
    // 条件删除
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    lqw.eq(User::getName, "张三");
    int result3 = userMapper.delete(lqw);
    System.out.println("影响行数:" + result3);
    
    // map条件删除
    Map<String, Object> map = new HashMap<>();
    map.put("name", "李四");
    int result4 = userMapper.deleteByMap(map);
    System.out.println("影响行数:" + result4);
}

总结

MyBatis-Plus是基于MyBatis的增强工具,它在不改变原有功能的基础上提供了强大的CRUD操作能力。通过继承BaseMapper 接口,开发者无需编写 XML 配置即可获得基本的数据库操作功能;支持 QueryWrapperLambdaQueryWrapper进行灵活的条件查询。整体而言,MyBatis-Plus极大地提升了开发效率,是Spring Boot 项目中处理数据持久层的优秀选择。

相关推荐
板板正4 分钟前
SpringAI——向量存储(vector store)
java·spring boot·ai
野生技术架构师10 分钟前
Spring Boot 定时任务与 xxl-job 灵活切换方案
java·spring boot·后端
苹果醋31 小时前
Java并发编程-Java内存模型(JMM)
java·运维·spring boot·mysql·nginx
你怎么知道我是队长1 小时前
C语言---编译的最小单位---令牌(Token)
java·c语言·前端
Elieal2 小时前
Java 链表完全指南:从基础到力扣简单题实战
java·leetcode·链表
寒士obj2 小时前
SpringBoot中的条件注解
java·spring boot·后端
pengzhuofan2 小时前
Java设计模式-外观模式
java·设计模式·外观模式
Emrys_2 小时前
AQS 深入解析
java
超级小忍3 小时前
从零开始:JDK 在 Windows、macOS 和 Linux 上的下载、安装与环境变量配置
java·windows·macos
.鸣3 小时前
Java学习笔记:IDEA简单使用技巧
java·学习