MyBatisPlus基础操作之增删改查指南

 更新时间:2026年06月27日 09:00:50   作者:不应该热爱  
这段文章详细介绍了MyBatis Plus(MP)框架中的的条件构造器Wrapper及其常用方法,包括插入、删除、更新操作,还介绍了Lambda条件构造器及自定义SQL的实现法,涵盖数据操作的多种场景

一、基本使用

下列涉及的User表如下所示:

1.1 插入数据

我们可以使用insert方法来实现数据的插入。

示例:

    @Test
    public void testInsert(){
        User user = new User();
        user.setUserName("fff33");
        user.setPassword("77888");
        int r = userMapper.insert(user);
        System.out.println(r);
    }

1.2 删除操作

我们可以使用deleteXXX方法来实现数据的删除。

示例:

    @Test
    public void testDelete(){
        List<Integer> ids = new ArrayList<>();
        ids.add(5);
        ids.add(6);
        ids.add(7);
        int i = userMapper.deleteBatchIds(ids);
        System.out.println(i);
    }
    @Test
    public void testDeleteById(){
        int i = userMapper.deleteById(8);
        System.out.println(i);
    }
    @Test
    public void testDeleteByMap(){
        Map<String, Object> map = new HashMap<>();
        map.put("name","提姆");
        map.put("age",22);
        int i = userMapper.deleteByMap(map);
        System.out.println(i);
    }

这里的deleteByMap实际执行的操作如下:

1.3 更新操作

我们可以使用updateXXX方法来实现数据的删除。

示例:

    @Test
    public void testUpdate(){
        //把id为2的用户的年龄改为14
        User user = new User();
        user.setId(2L);
        user.setAge(14);
        int i = userMapper.updateById(user);
        System.out.println(i);
    }

二、条件构造器Wrapper

概述 :我们在实际操作数据库的时候会涉及到很多的条件。所以MP为我们提供了一个功能强大的条件构造器 Wrapper 。

使用它可以让我们非常方便的构造条件。

其继承体系如下:

在其子类 AbstractWrapper 中提供了很多用于构造Where条件的方法。 

AbstractWrapper 的子类 QueryWrapper 则额外提供了用于针对Select语法的 select 方法。可以用来设置查询哪些列。

AbstractWrapper 的子类 updateWrapper 则额外提供了用于针对Set语法的set方法。可以用来设置对哪些列进行更新。

2.1 常用AbstractWrapper方法

  • eq:equals,等于 =
  • gt:greater than ,大于 >
  • ge:greater than or equals,大于等于≥
  • lt:less than,小于<
  • le:less than or equals,小于等于≤
  • between:相当于SQL中的BETWEEN
  • like:模 糊匹配。like("name","黄"),相当于SQL的name like '%黄%'
  • likeRight:模糊匹配右半边。 likeRight("name","黄"),相当于SQL的name like '黄%'
  • likeLeft:模糊匹配左半边。 likeLeft("name","黄"),相当于SQL的name like '%黄'
  • and:SQL连接符AND
  • or:SQL连接符OR
  • in: in(“age",{1,2,3})相当于 age in(1,2,3)
  • groupBy: groupBy("id","name")相当于 group by id,name
  • orderByAsc :orderByAsc("id","name")相当于 order by id ASC,name ASC
  • orderByDesc :orderByDesc ("id","name")相当于 order by id DESC,name DESC

2.1.1 示例一

SQL语句如下:

SELECT 
    id,user_name,PASSWORD,NAME,age,address 
FROM 
    USER 
WHERE 
    age > 18 AND address = '狐山'

如果用Wrapper写法如下: 

 @Test
 public void testWrapper01(){
     QueryWrapper<User> wrapper = new QueryWrapper<>();
     wrapper.gt("age",18);
     wrapper.eq("address","狐山");
     List<User> users = userMapper.selectList(wrapper);
     System.out.println(users);
 }

我们可以通过调试来验证这一观点,调用wrapper的getCustomSqlSegment方法: 

2.2.2示例二

SQL语句如下:

SELECT 
    id,user_name,PASSWORD,NAME,age,address 
FROM 
    USER 
WHERE 
    id IN(1,2,3) AND 
    age BETWEEN 12 AND 29 AND 
    address LIKE '%山%'

如果用Wrapper写法如下:

    @Test
    public void testWrapper02(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.in("id",1,2,3);
        wrapper.between("age",12,29);
        wrapper.like("address","山");
        List<User> users = userMapper.selectList(wrapper);
        System.out.println(users);
    }

2.2.3 示例三

SQL语句如下:

SELECT 
    id,user_name,PASSWORD,NAME,age,address 
FROM 
    USER 
WHERE 
    id IN(1,2,3) AND 
    age > 10 
    ORDER BY 
    age DESC

如果用Wrapper写法如下:

@Test
 public void testWrapper03(){
     QueryWrapper<User> queryWrapper = new QueryWrapper<>();
     queryWrapper.in("id",1,2,3);
     queryWrapper.gt("age",10);
     queryWrapper.orderByDesc("age");
     List<User> users = userMapper.selectList(queryWrapper);
     System.out.println(users);
 }

2.2 常用QueryWrapper方法

QueryWrapper的 select 方法可以设置要查询的列。

2.2.1 示例一

select(String... sqlSelect) 方法的测试为要查询的列名

SQL语句如下:

SELECT 
    id,user_name
FROM 
    USER 

MP写法如下:

@Test
 public void testSelect01(){
     QueryWrapper<User> queryWrapper = new QueryWrapper<>();
     queryWrapper.select("id","user_name");
     List<User> users = userMapper.selectList(queryWrapper);
     System.out.println(users);
 }

2.2.2 示例二

select(Class entityClass, Predicate predicate)

方法的第一个参数为实体类的字节码对象,第二个参数为Predicate类型,即函数式接口,可以使用lambda的写法,过滤要查询的字段 (主键除外) 。

SELECT 
    id,user_name
FROM 
    USER 

MP写法如下:

    @Test
    public void testSelect02(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(User.class, new Predicate<TableFieldInfo>() {
            @Override
            public boolean test(TableFieldInfo tableFieldInfo) {
                return "user_name".equals(tableFieldInfo.getColumn());
            }
        });
        List<User> users = userMapper.selectList(queryWrapper);
        System.out.println(users);
    }

分析: 

第一次循环(id是默认有的,所以不参与):

第二次循环:

这个方法内部其实就是遍历数据库中相对应的User表,tableFieldInfo的column属性会通过循环的方式拿到每个表的属性,然后进行匹配,如果匹配结果为true,就返回这个属性所对应的结果。  

2.2.3 示例三(常用)

select(Predicate predicate)

方法第一个参数为Predicate类型,可以使用lambda的写法,过滤要查询的字段 (主键除外) 。

 SQL语句如下:

SELECT 
    id,user_name,PASSWORD,NAME,age 
FROM 
    USER

 就是不想查询address这列,其他列都查询了。

MP写法如下:

 @Test
    public void testSelect03(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(new User());
        queryWrapper.select(new Predicate<TableFieldInfo>() {
            @Override
            public boolean test(TableFieldInfo tableFieldInfo) {
                return !"address".equals(tableFieldInfo.getColumn());
            }
        });
        List<User> users = userMapper.selectList(queryWrapper);
        System.out.println(users);
    }

分析: 

这是由于这个select方法需要传递entity对象,没有传递无法调用。

2.3 常用UpdateWrapper方法

我们前面在使用update方法时需要创建一个实体类对象传入,用来指定要更新的列及对应的值。但是如 果需要更新的列比较少时,创建这么一个对象显的有点麻烦和复杂。

我们可以使用UpdateWrapper的set方法来设置要更新的列及其值。同时这种方式也可以使用Wrapper 去指定更复杂的更新条件。

2.3.1 示例一

SQL语句如下:

UPDATE 
    USER
SET 
    age = 99
where 
    id > 1

我们想把id大于1的用户的年龄修改为99,则可以使用如下写法:

@Test
 public void testUpdateWrapper(){
     UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
     updateWrapper.gt("id",1);
     updateWrapper.set("age",99);
     userMapper.update(null,updateWrapper);
 }

三、 Lambda条件构造器

我们前面在使用条件构造器时列名都是用字符串的形式去指定。这种方式无法在编译期确定列名的合法 性。

所以MP提供了一个Lambda条件构造器可以让我们直接以实体类的方法引用的形式来指定列名。这样就 可以弥补上述缺陷。 

3.1 示例一

要执行的查询对应的SQL如下:

SELECT 
    id,user_name,PASSWORD,NAME,age,address 
FROM 
    USER 
WHERE 
    age > 18 AND address = '狐山'

 如果使用之前的条件构造器写法如下:

@Test
 public void testLambdaWrapper(){
     QueryWrapper<User> queryWrapper = new QueryWrapper();
     queryWrapper.gt("age",18);
     queryWrapper.eq("address","狐山");
     List<User> users = userMapper.selectList(queryWrapper);
 }

如果使用Lambda条件构造器写法如下:

@Test
 public void testLambdaWrapper2(){
     LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
     queryWrapper.gt(User::getAge,18);
     queryWrapper.eq(User::getAddress,"狐山");
     List<User> users = userMapper.selectList(queryWrapper);
 }

四、实现自定义SQL

4.1 准备工作

 SQL文件:

CREATE TABLE `orders` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `price` int(11) DEFAULT NULL COMMENT '价格',
 `remark` varchar(100) DEFAULT NULL COMMENT '备注',
 `user_id` int(11) DEFAULT NULL COMMENT '用户id',
 `update_time` timestamp NULL DEFAULT NULL COMMENT '更新时间',
 `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
 `version` int(11) DEFAULT '1' COMMENT '版本',
 `del_flag` int(1) DEFAULT '0' COMMENT '逻辑删除标识,0-未删除,1-已删除',
 `create_by` varchar(100) DEFAULT NULL COMMENT '创建人',
 `update_by` varchar(100) DEFAULT NULL COMMENT '更新人',
 PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
INSERT INTO `orders`(`id`,`price`,`remark`,`user_id`,`update_time`,`create_time`,`version`,`del_flag`,`create_by`,`update_by`) 
VALUES (1,2000,'无',2,'2021-08-24 21:02:43','2021-08-24 21:02:46',1,0,NULL,NULL),
       (2,3000,'无',3,'2021-08-24 21:03:32','2021-08-24 21:03:35',1,0,NULL,NULL),
       (3,4000,'无',2,'2021-08-24 21:03:39','2021-08-24 21:03:41',1,0,NULL,NULL);

创建实体类:

package com.fox.mp.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Orders  {
      private Long id;
      /**
      * 价格
      */
      private Integer price;
      /**
      * 备注
      */
      private String remark;
      /**
      * 用户id
      */
      private Integer userId;
      /**
      * 更新时间
      */
      private LocalDateTime updateTime;
      /**
      * 创建时间
      */
      private LocalDateTime createTime;
      /**
      * 版本
      */
      private Integer version;
      /**
      * 逻辑删除标识,0-未删除,1-已删除
      */
      private Integer delFlag;

 }

4.2 Mybatis方法

定义方法

public interface UserMapper extends BaseMapper<User> {
    User findMyUser(Long id);
}

在Mapper接口中定义方法,这里没用@Mapper注解的原因是因为在启动类上设置了扫描组件: 

创建XML文件

 先在yml文件中配置xml文件的存放目录:

mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml

创建对应的xml映射文件,这里我们是使用MybatisX这个插件快速生成对应的xml文件:

 在xml文件中书写对应的SQL语句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.fox.mp.mapper.UserMapper">
    <select id="findMyUser" resultType="com.fox.mp.domain.User">
        select * from tb_user where id = #{id}
    </select>
</mapper>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Security实现多次登录失败后账户锁定功能

    Spring Security实现多次登录失败后账户锁定功能

    当用户多次登录失败的时候,我们应该将账户锁定,等待一定的时间之后才能再次进行登录操作。今天小编给大家分享Spring Security实现多次登录失败后账户锁定功能,感兴趣的朋友一起看看吧
    2019-11-11
  • spring集成httpclient配置的详细过程

    spring集成httpclient配置的详细过程

    spring框架是一个非常强大的框架这里就不多说了,那么主要是介绍spring与httpclient的整合集成过程,感兴趣的朋友跟随小编一起看看吧
    2021-07-07
  • 浅析Spring获取Bean的九种方法详解

    浅析Spring获取Bean的九种方法详解

    随着SpringBoot的普及,Spring的使用也越来越广,在某些场景下,我们无法通过注解或配置的形式直接获取到某个Bean。比如,在某一些工具类、设计模式实现中需要使用到Spring容器管理的Bean,此时就需要直接获取到对应的Bean,这篇文章主要介绍了Spring获取Bean的九种方法
    2023-01-01
  • 使用mybatisPlus生成oracle自增序列遇到的坑及解决

    使用mybatisPlus生成oracle自增序列遇到的坑及解决

    这篇文章主要介绍了使用mybatisPlus生成oracle自增序列遇到的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Eclipse常用快捷键大全

    Eclipse常用快捷键大全

    这篇文章主要介绍了Eclipse常用快捷键大全,较为详细的针对eclipse中各种应用中使用快捷键进行了分类总结,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • Java中Class类的作用与深入理解

    Java中Class类的作用与深入理解

    这篇文章主要介绍了Java中Class类的作用与深入理解的相关资料,希望通过本文能帮助到大家让大家理解这部分内容,需要的朋友可以参考下
    2017-10-10
  • springmvc使用JSR-303进行数据校验实例

    springmvc使用JSR-303进行数据校验实例

    本篇文章主要介绍了详解springmvc使用JSR-303进行数据校验,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-02-02
  • JDK8接口的默认与静态方法-接口与抽象类的区别详解

    JDK8接口的默认与静态方法-接口与抽象类的区别详解

    这篇文章主要介绍了JDK8接口的默认与静态方法-接口与抽象类的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下
    2019-06-06
  • Java Spring 声明式事务详解

    Java Spring 声明式事务详解

    这篇文章主要介绍了spring 声明式事务实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-09-09
  • 基于Java实现简单的时序数据压缩算法

    基于Java实现简单的时序数据压缩算法

    这篇文章主要为大家详细介绍了如何利用Java语言实现简单易懂的时序数据压缩算法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-06-06

最新评论