MyBatisPlus基础操作之增删改查

目录

一、基本使用

[1.1 插入数据](#1.1 插入数据)

[1.2 删除操作](#1.2 删除操作)

[1.3 更新操作](#1.3 更新操作)

二、条件构造器Wrapper

[2.1 常用AbstractWrapper方法](#2.1 常用AbstractWrapper方法)

[2.1.1 示例一](#2.1.1 示例一)

[2.2.2 示例二](#2.2.2 示例二)

[2.2.3 示例三](#2.2.3 示例三)

[2.2 常用QueryWrapper方法](#2.2 常用QueryWrapper方法)

[2.2.1 示例一](#2.2.1 示例一)

[2.2.2 示例二](#2.2.2 示例二)

[2.2.3 示例三(常用)](#2.2.3 示例三(常用))

[2.3 常用UpdateWrapper方法](#2.3 常用UpdateWrapper方法)

[2.3.1 示例一](#2.3.1 示例一)

[三、 Lambda条件构造器](#三、 Lambda条件构造器)

[3.1 示例一](#3.1 示例一)

四、实现自定义SQL

[4.1 准备工作](#4.1 准备工作)

[4.2 Mybatis方法](#4.2 Mybatis方法)


一、基本使用

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

1.1 插入数据

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

示例:

java 复制代码
    @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方法来实现数据的删除。

示例:

java 复制代码
    @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方法来实现数据的删除。

示例:

java 复制代码
    @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语句如下:

css 复制代码
SELECT 
    id,user_name,PASSWORD,NAME,age,address 
FROM 
    USER 
WHERE 
    age > 18 AND address = '狐山'

如果用Wrapper写法如下:

java 复制代码
 @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语句如下:

java 复制代码
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写法如下:

java 复制代码
    @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语句如下:

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

如果用Wrapper写法如下:

java 复制代码
@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语句如下:

java 复制代码
SELECT 
    id,user_name
FROM 
    USER 

MP写法如下:

java 复制代码
@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的写法,过滤要查询的字段 (主键除外) 。

java 复制代码
SELECT 
    id,user_name
FROM 
    USER 

MP写法如下:

java 复制代码
    @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语句如下:

java 复制代码
SELECT 
    id,user_name,PASSWORD,NAME,age 
FROM 
    USER

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

MP写法如下:

java 复制代码
 @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语句如下:

java 复制代码
UPDATE 
    USER
SET 
    age = 99
where 
    id > 1

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

java 复制代码
@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如下:

java 复制代码
SELECT 
    id,user_name,PASSWORD,NAME,age,address 
FROM 
    USER 
WHERE 
    age > 18 AND address = '狐山'

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

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

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

java 复制代码
@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文件:

java 复制代码
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);

创建实体类:

java 复制代码
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方法

定义方法

java 复制代码
public interface UserMapper extends BaseMapper<User> {
    User findMyUser(Long id);
}

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

创建XML文件

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

java 复制代码
mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml

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

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

XML 复制代码
<?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>
相关推荐
罗政几秒前
PDF书籍《手写调用链监控APM系统-Java版》第12章 结束
java·开发语言·pdf
GraduationDesign5 分钟前
基于SpringBoot的蜗牛兼职网的设计与实现
java·spring boot·后端
今天不学习明天变拉吉14 分钟前
大批量数据导入接口的优化
java·excel
小手cool15 分钟前
取多个集合的交集
java
全栈老实人_18 分钟前
农家乐系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
customer0820 分钟前
【开源免费】基于SpringBoot+Vue.JS安康旅游网站(JAVA毕业设计)
java·vue.js·spring boot·后端·kafka·开源·旅游
点点滴滴的记录37 分钟前
Java的CompletableFuture实现原理
java·开发语言·javascript
xiaolingting38 分钟前
Java 引用是4个字节还是8个字节?
java·jvm·引用·指针压缩
一只傻小白,43 分钟前
JAVA项目中freemarker静态模板技术
java·开发语言
袁庭新43 分钟前
Spring Boot项目接收前端参数的11种方式
java·springboot·袁庭新·如何接收前端数据·boot接收数据