SpringBoot 集成 MybatisPlus 二:CURD

27 阅读7分钟

0 前置数据

首先创建这样一张数据表

CREATE TABLE user (id INT(11) NOT NULL, username VARCHAR(50), gendar CHAR(2) , remark VARCHAR(50));

并向表中插入多条数据

1 简单查询

对于简单的查询,例如根据某一个字段或ID进行查询,使用 MyBatisPlus 可以直接进行。

1.1 根据ID查询

代码语言:txt

**复制

@Test
public void getUser(){
    User user = userMapper.selectById(1);
    System.out.println(user);
}

效果等同于如下SQL语句

1.2 根据某一个字段进行查询

代码语言:txt

**复制

@Test
public void getUserByField(){
    Map<String, Object> map = new HashMap<>();
    map.put("id", "1");
    List<User> user = userMapper.selectByMap(map);
    user.forEach(System.out::println);
}

因为只使用了一个属性进行查询,效果也和 1.1 中相同。

1.3 根据多个字段进行联合查询

代码语言:txt

@Test
public void getUserByFields(){
    Map<String, Object> map = new HashMap<>();
    map.put("id", "1");
    map.put("username", "admin");
    List<User> user = userMapper.selectByMap(map);
    user.forEach(System.out::println);
}

多个字段的查询,等同于如下效果

2 条件查询

2.1 条件构造器 QueryWrapper 对象

那么如果想要实现复杂一些的查询呢,应该怎么做?

MyBatisPlus 中的 QueryWrapper 对象,可以让用户自由构造SQL查询条件,可以快速上手并且有效提高开发效率。

表达式含义
or条件或
and条件且
in在...中
notin不在...中
eq等于
ne不等于
gt大于
ge大于等于
lt小于
le小于等于
between在...范围
like模糊查询,含有
notlike模糊查询,不含有
groupBy分组
having分组后筛选
orderBy数据排序
isNull空值判断
isNotNull非空判断
exists存在
notExists不存在

需要注意的是:

条件查询中的列名,必须是数据库中的列名,而不是我们所创建实体类中的属性名。

2.2 查询举例

查询 username 中包含“zhang”并且性别为女的记录

代码语言:

@Test
public void getUserUseAnd(){
    QueryWrapper<User> wrapper = new QueryWrapper<User>();
    QueryWrapper<User> select = wrapper.like("username", "zhang").eq("gendar", "女");
    List<User> users = userMapper.selectList(select);
    users.forEach(System.out::println);
}

输出结果:

User{id=2, username='zhangsan', gendar='女', remark='销售人员'}

这里的 like() 方法相当于 SQL 语句中的 %zhang%;如果我们只想对某一个方向的查询进行模糊,如果左侧模糊或右侧模糊,可以使用 likeLeft() 或是 likeRight() 即可实现 %zhang 或 zhang% 的效果。

2.3 聚合查询-mybatisplus实现group by

有时需要对查询的结果使用聚合函数进行计算。

如:查询不同性别的用户数量,当数量等于0时不统计

首先需要按性别对用户表进行分组;然后计算各分组的数量;按数量对结果进行筛选,要求大于0

此文以 count() 函数举例,其它函数的使用方法可以进行参考。

代码语言:java

@Test
public void getUserUseGroup() {
    QueryWrapper<User> wrapper = new QueryWrapper<User>();
    wrapper.select("gendar", "COUNT(gendar) as count").groupBy("gendar").having("count > 0");
    List<Map<String, Object>> objects = userMapper.selectMaps(wrapper);
    objects.forEach(System.out::println);
}

在控制台可以看到生成的SQL语句及执行过程:

==> Preparing: SELECT gendar,COUNT(gendar) as count FROM user GROUP BY gendar HAVING count > 0

==> Parameters:

<== Columns: gendar, count

<== Row: 女, 2

<== Row: 男, 3

<== Total: 2

执行结果如下:

{gendar=女, count=2}

{gendar=男, count=3}

类似地,如果想要使用其他聚合函数,可以在 select() 方法中直接使用 SQL 语句实现。

1 插入记录

1.1 以普通方式插入记录

向 User 表中插入一条记录。

创建一个 User 对象,调用 insert() 方法,即可实现向数据表中插入数据

代码语言:java

**复制

@Test
public void addUserTest(){
    User user = new User();
    user.setUsername("韩梅梅");
    user.setGendar("女");
    user.setRemark("大堂经理");
    int insert = userMapper.insert(user);
    System.out.println(insert);
}

执行后,可以在控制台中看到 MybatisPlus 向数据库发送的 SQL 语句如下:

==> Preparing: INSERT INTO user ( id, username, gendar, remark ) VALUES ( ?, ?, ?, ? )

==> Parameters: -154062847(Integer), 韩梅梅(String), 女(String), 大堂经理(String)

<== Updates: 1

因为没有对 ID 属性进行指定,程序随机生成了一条内容,这显然不是我们所期望的,可以在执行程序时设置该字段内容。

代码语言:java

**复制

@Test
public void addUserTest(){
    User user = new User();
    user.setId(7);
    user.setUsername("韩梅梅");
    user.setGendar("女");
    user.setRemark("大堂经理");
    int insert = userMapper.insert(user);
    System.out.println(insert);
}

数据入库后效果如下:

那么,如果id为主键,一般为自增序列,要如何插入呢?

1.2 以字段自增方式插入记录

1.2.1 修改数据表

原数据表创建语句为:

CREATE TABLE User (

id INT NOT NULL,

username VARCHAR(50) NULL DEFAULT NULL,

gendar CHAR(2) NULL DEFAULT NULL,

remark VARCHAR(50) NULL DEFAULT NULL

);

在数据表中添加 ID 字段为主键,并且将该字段设置为自动增长:

ALTER TABLE user ADD PRIMARY KEY(id);

ALTER TABLE user modify id INT(11) AUTO_INCREMENT;

1.2.2 修改实体类

修改实体类属性 id 的注解,使用 @TableId 标识出id字段为主键,并且将该字段设置为自动增长 IdType.AUTO

修改后的 User 类如下:

代码语言:java

**复制

package com.test.pojo;

import com.baomidou.mybatisplus.annotation.*;

@TableName(value = "user")
public class User {
    @TableId(value = "id", type = IdType.AUTO)
    Integer id;
    String username;
    String gendar;
    String remark;

    @TableField(value = "COUNT(*)", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
    Integer count;

    public Integer getGen() {
        return count;
    }

    public void setGen(Integer gen) {
        this.count = gen;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getGendar() {
        return gendar;
    }

    public void setGendar(String gendar) {
        this.gendar = gendar;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + ''' +
                ", gendar='" + gendar + ''' +
                ", remark='" + remark + ''' +
                ", count=" + count +
                '}';
    }
}

1.2.3 插入数据

代码语言:java

**复制

@Test
public void addUserTest(){
    User user = new User();
    user.setUsername("李磊");
    user.setGendar("男");
    user.setRemark("英语老师");
    int insert = userMapper.insert(user);
    System.out.println(insert);
}

在控制台中看到 MybatisPlus 向数据库发送的 SQL 语句中,不再有ID字段了:

==> Preparing: INSERT INTO user ( username, gendar, remark ) VALUES ( ?, ?, ? )

==> Parameters: 李磊(String), 男(String), 英语老师(String)

<== Updates: 1

插入后数据表中,新记录的ID自动设置为8:

2 修改记录

2.1 根据ID修改

调用 updateById() 方法修改记录,方法中必须传入带有ID属性的对象。

代码语言:java

**复制

@Test
public void updateUserById(){
    User user = new User();
    user.setId(8);
    user.setRemark("美术老师");
    int insert = userMapper.updateById(user);
    System.out.println(insert);
}

这种方式可对指定id的记录进行修改,因此,只能修改一条记录。

2.2 根据筛选条件修改

当需要按照指定条件筛选,并对筛选后的记录进行批量修改时,就要考虑这种使用方式。

需要先创建一个 UpdateWrapper 对象,需要修改的内容可以使用 set() 方法进行设置,筛选条件和查询时类似。

注意: 在 set() 方法及 UpdateWrapper 中引用的字符串,都是数据表中的列名,而不是实体类的属性名。

比如:对 remark 字段中包含“人员”信息的,将其 remark 修改为 “职能部门人员”:

代码语言:java

**复制

@Test
public void updateUserTest(){
    User user = new User();
    UpdateWrapper<User> wrapper = new UpdateWrapper<>();
    wrapper.set("remark", "职能部门人员");
    wrapper.like("remark", "人员");
    int insert = userMapper.update(new User(), wrapper);
    System.out.println(insert);
}

在控制台可以看到执行的SQL语句如下:

==> Preparing: UPDATE user SET remark=? WHERE (remark LIKE ?)

==> Parameters: 职能部门人员(String), %人员%(String)

<== Updates: 4

执行后数据内容变化如下:

3 删除记录

3.1 根据ID删除

调用 deleteById() 方法,传入仅设置了id属性的对象,此方法可删除一条记录。

删除 id 为 -154062847 的记录:

代码语言:java

**复制

@Test
public void deleteUserById(){
    User user = new User();
    user.setId(-154062847);
    int res = userMapper.deleteById(user);
    System.out.println(res);
}

==> Preparing: DELETE FROM user WHERE id=?

==> Parameters: -154062847(Integer)

<== Updates: 1

使用对象的方式来删除记录,需要创建对象,还是有些麻烦,也可以省去对象的创建,直接根据id来删除。

代码语言:java

**复制

@Test
public void deleteUserById(){
    int res = userMapper.deleteById(1);
    System.out.println(res);
}

3.2 根据ID列表删除

如果想要根据多个ID批量删除,可以调用 deleteBatchIds(),传入集合类对象,在集合类中设置想要批量删除的id集合。

删除 id 分别为 1,2 的记录:

代码语言:java

**复制

@Test
public void deleteUserByIds(){
    List<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(2);
    int res = userMapper.deleteBatchIds(ids);
    System.out.println(res);
}

==> Preparing: DELETE FROM user WHERE id IN ( ? , ? )

==> Parameters: 1(Integer), 2(Integer)

<== Updates: 2

3.3 根据指定字段内容删除

将指定字段及对应内容,放入到 Map 中,调用 deleteByMap() 方法,删除对应记录。

需要注意的是,Map 中所有字段都为“且”的关系。Map 对象中键,都是数据表中的列名,不是实体类的对象名。

删除 username 为 “lisi” 并且 remark 为 “大堂经理” 的记录:

代码语言:java

**复制

@Test
public void deleteUserByMap(){
    Map<String, Object> map = new HashMap<>();
    map.put("username", "lisi");
    map.put("remark", "大堂经理");
    int res = userMapper.deleteByMap(map);
    System.out.println(res);
}

==> Preparing: DELETE FROM user WHERE remark = ? AND username = ?

==> Parameters: 大堂经理(String), lisi(String)

<== Updates: 0

通过这种方式可以删除满足条件的单条记录或批量记录。

3.4 根据查询结果删除

调用 delete() 方法,并传入 QueryWrapper 对象,在 QueryWrapper 对象中如同查询一样,将查询出的记录进行删除。

删除 remark 中包含了 “职能” 字符串的所有记录:

代码语言:java

**复制

@Test
public void deleteUserByWrapper(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.like("remark", "职能");
    int res = userMapper.delete(wrapper);
    System.out.println(res);
}

==> Preparing: DELETE FROM user WHERE (remark LIKE ?)

==> Parameters: %职能%(String)

<== Updates: 3