java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatisPlus增删改查

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

作者:不应该热爱

这段文章详细介绍了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方法

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>

总结

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

您可能感兴趣的文章:
阅读全文