mybatisPlus框架

news2024/11/29 6:37:09

1、特性

无侵入 :只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小 :启动即会自动注入基本 CURD ,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作 :内置通用 Mapper 、通用 Service ,仅仅通过少量配置即可实现单表大
部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用 :通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字
段写错
支持主键自动生成 :支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence ),可
自由配置,完美解决主键问题
支持 ActiveRecord 模式 :支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进
行强大的 CRUD 操作
支持自定义全局通用操作 :支持全局通用方法注入( Write once, use anywhere
内置代码生成器 :采用代码或者 Maven 插件可快速生成 Mapper Model Service
Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件 :基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分
页等同于普通 List 查询
分页插件支持多种数据库 :支持 MySQL MariaDB Oracle DB2 H2 HSQL
SQLite Postgre SQLServer 等多种数据库
内置性能分析插件 :可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快
速揪出慢查询
内置全局拦截插件 :提供全表 delete update 操作智能分析阻断,也可自定义拦截规
则,预防误操作

2、操作

1、创建一个User用户表用于测试

# Host: localhost  (Version 5.7.23-log)
# Date: 2023-12-10 14:21:50
# Generator: MySQL-Front 6.0  (Build 2.20)


#
# Structure for table "tb_user"
#

CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) DEFAULT NULL COMMENT '用户名',
  `password` varchar(32) DEFAULT NULL COMMENT '密码',
  `role` varchar(10) DEFAULT NULL COMMENT '角色:0:管理员  1:普通用户',
  `sex` int(11) DEFAULT NULL COMMENT '性别,0:女 1:男',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `createTime` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

#
# Data for table "tb_user"
#

INSERT INTO `tb_user` VALUES (1,'admin','123456','0',1,25,'2022-10-23 00:12:36'),(6,'张曼玉','123456','1',1,18,'2022-10-23 00:12:44'),(14,'a3','122','1',1,313,'2023-10-17 21:31:48'),(15,'aaa','123456','1',1,111,'2023-11-13 20:26:10'),(17,'aaa','weqe','1',0,NULL,'2023-11-20 18:33:09');

 

2、新建maven工程

3、导入依赖

<dependencies>
    <!-- MyBatisPlus -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.2</version>
    </dependency>
   
    <!-- MySql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.30</version>
    </dependency>
    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3307/mybatis?
useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8

 

4、配置application.properties

5、插件lombok下载

Lombok 提供的常用注解:
@Getter/@Setter :用在类或属性上,用在类上可以作用于这个类的所有属性,写在属性 上只作用于属性名,再也不用自己手写setter getter 方法了
@ToString :用在类上,可以自动覆写 toString 方法,当然还可以加其他参数,例如
@ToString(exclude=”id”) 排除 id 属性,或者 @ToString(callSuper=true, includeFieldNames=true)调用父类的 toString 方法,包含所有属
@EqualsAndHashCode :用在类上,自动生成 equals 方法和 hashCode 方法
@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor :用 在类上,自动生成无参构造和使用所有参数的构造函数以及把所有@NonNull 属性作为参数的构造函数
@RequiredArgsConstructor 主要是对当前类中带有 final 的属性进行属性注入
@Data :注解在类上,相当于同时使用了 @ToString @EqualsAndHashCode
@Getter @Setter @RequiredArgsConstrutor 这些注解,对于 POJO 十分有用
@Value :用在类上,是 @Data 的不可变形式,相当于为属性添加 final 声明,只提供 getter方法,而不提供setter 方法
@Slf4j : 自动创建 Slf4j 日志对象 log ,用于记录系统日志信息

 6、创建实体类

package com.cqh.entity;


import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
@Data //@Data : 注解在类上,提供类的get、set、equals、hashCode、canEqual、toString、无参构造方法,没有有参构造方法。
@AllArgsConstructor // 全部参数构造方法
@NoArgsConstructor //无参数构造方法
@TableName("tb_user")
public class User {


    @TableId
    private int id;
    private String username;
    private String password;
    private String role;
    private int sex;
    private int age;
    @TableField(value = "createTime")
    private Date createTime;
}

 7、创建userMapper接口

8、完善启动类

为了能够让 SpringBoot 扫描并且识别此组件,我们需要在 SpringBoot 启动类上开启 Mapper 接口
扫描功能,添加 @MapperScan() 注解

 

package com.cqh;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.cqh.mapper")
@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class,args);
    }
}

9、测试

查询所有

 

package com.cqh;

import com.cqh.entity.User;
import com.cqh.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

//查询全部用户
//此方法需要我们传递Wrapper对象,此对象是条件构造器,我们现在要查询全部用户先不用,所以传null即可
    @Test
    public void test01(){

        List<User> users = userMapper.selectList(null);
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
}
 为了方便查看配置日志

# 配置日志
mybatis-plus.configuration.logimpl=org.apache.ibatis.logging.stdout.StdOutImpl
 添加user
//插入数据
    @Test
    public void test02(){
        User user1 = new User();
        user1.setUsername("xiaoMin");
        user1.setPassword("123456");
        user1.setAge(11);
        user1.setRole("0");
        user1.setSex(1);

        int insert = userMapper.insert(user1);
        System.out.println("insert = " + insert);

    }

 删除功能
BaseMapper 中提供了 5 个删除方法
//用于删除数据库中的记录。它接受一个类型为 Serializable 的参数 id,表示要删除的记录的唯一标识符。
根据Map删除对应数据
//根据map删除

    @Test
    public void deleteTest(){
        Map<String,Object> map = new HashMap<>();
        map.put("username","xiaoMin");
        map.put("age",11);
        int num = userMapper.deleteByMap(map);
        System.out.println(num);
    }
 根据多个id进行批量删除

 

//根据多个id进行批量删除
    @Test
    public void deleteTest2(){
        ArrayList<Integer> ids = new ArrayList<>();
        ids.add(15);
        ids.add(17);
        int num = userMapper.deleteBatchIds(ids);
        System.out.println(num);
    }

 

 

 多条件删除
 //根据多个条件进行删除
    @Test
    public void deleteTest3(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username","a3");
        userQueryWrapper.eq("sex",1);
        int num = userMapper.delete(userQueryWrapper);
        System.out.println(num);
    }

 

 修改功能

修改方法BaseMapper中提供了两个

 

根据id修改

 


    //根据id修改
    @Test
    public void updateTest(){
        User user = new User();
        user.setId(6);
        user.setUsername("李四");
        int num = userMapper.updateById(user);
        System.out.println(num);
    }
 查询功能
下图中的两个方法,分别是通过单个 id 查询数据,和 id 集合来查询数据,

此方法为根据Map中传递的条件进行查询 

 

 //根据Map中传递的条件进行查询
    @Test
    public void selectTest(){
        Map<String,Object> map = new HashMap<>();
        map.put("id",6);
        map.put("username","李四");
        List<User> users = userMapper.selectByMap(map);
        users.forEach(user -> System.out.println(user));
    }

 此方法Wrapper条件构造器传递参数为null表示查询全部数据

注意:所有的CRUD方法中只要涉及到Wrapper条件构造器的如果不需要使用都可以传入为
null,但是要注意一般查询可以传入,但是修改和删除一般不可以,因为如果删除和修改没有条
件会导致影响全部数据

 

新增功能

//插入数据
    @Test
    public void test02(){
        User user1 = new User();
        user1.setUsername("xiaoMin");
        user1.setPassword("123456");
        user1.setAge(11);
        user1.setRole("0");
        user1.setSex(1);

        int insert = userMapper.insert(user1);
        System.out.println("insert = " + insert);

    }

 有一个问题就是没有主键返回

 

其实这里 MyBatis-Plus 是通过雪花算法来进行自动生成的 id ,但是要 注意: 我们的主键必须叫
id,并且必须是包装类型,否则不生效
常见主键生成策略
数据库自增长序列或字段:最常见的方式。利用数据库,全数据库唯一。
UUID :常见的方式。可以利用数据库也可以利用程序生成,一般来说全球唯一。
Redis 生成 ID :当使用数据库来生成 ID 性能不够要求的时候,我们可以尝试使用 Redis 来生成ID。这主要依赖于 Redis 是单线程的,所以也可以用生成全局唯一的 ID
Twitter snowflake( 雪花 ) 算法: snowflake Twitter 开源的分布式 ID 生成算法,结果是一个long 型的 ID
zookeeper 生成唯一 ID zookeeper 主要通过其 znode 数据版本来生成序列号,可以生成 32位和64 位的数据版本号,客户端可以使用这个版本号来作为唯一的序列号。
雪花算法
snowflake Twitter 开源的分布式 ID 生成算法,结果是一个 long 型的 ID
其核心思想是:使用 41bit 作为毫秒数, 10bit 作为机器的 ID 5 bit 是数据中心, 5 bit 的机器
ID ), 12bit 作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 ID ),最后还有
一个符号位,永远是 0
其中 MyBatis-Plus 中提供的一个注解 @TableId

 

 

(注意:表一定要是主键自增 )

修改User实体类

 现在主键返回了

自定义CRUD 

MyBatis-Plus BaseMapper 本身提供了很多通用的 CRUD 方法,但是由于我们的业务问题有的
时候必须要自定义一些方法
MyBatis-Plus 是在 MyBatis 的基础之上只做增强不做修改的即可,所以如果想要实
现自定义的方法,具体操作其实和 MyBatis 没有什么区别
配置
如果我们需要进行复杂映射就可能会涉及到映射文件 mapper.xml 那么这个文件位置的配置,我
们可以在 properties 配置文件中进行配置
# 指定mapper文件位置
mybatis-plus.mapper-locations = classpath*:/mapper/**/*.xml

测试
注解方式 

编写mapper

package com.cqh.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cqh.entity.User;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserMapper extends BaseMapper<User> {
    /**
     * 根据name查询数据
     * @param username
     * @return
     */
    @Select("select * from tb_user where username=#{username}")
    List<User> selectByName(String username);
}

编写测试方法 

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.cqh.mapper.UserMapper">

    <select id="selectByName" resultType="com.cqh.entity.User">
        select * from tb_user where username=#{username}
    </select>
</mapper>

 测试一下

 IService接口

通用 Service CRUD 封装 IService (opens new window) 接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混
淆,
泛型 T 为任意实体对象
建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承
Mybatis - Plus 提供的基类
对象 Wrapper 为 条件构造器
使用参考: MybatisPlus入门-CSDN博客

分页插件

Page: 该类继承了 IPage 类,实现了 简 单 分 页 模 型 如果你要实现自己的分页模型可以继承
Page 类或者实现 IPage

创建config开启分页

package com.cqh.config;

/**
 * @author cqh
 * @date 2023/12/10
 * @Description
 */

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
//开启扫描,注意包名不要写错(有了MyBatisPlus的配置类,我们就可以把所有的相关配置都写在这里)
@MapperScan("com.qf.mybatisplusdemo.mapper")
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new
                MybatisPlusInterceptor();
//分页插件
        mybatisPlusInterceptor.addInnerInterceptor(new
                PaginationInnerInterceptor(DbType.MYSQL));
        return mybatisPlusInterceptor;
    }
}

分页测试

 

    @Test
    public void PaginationInnerInterceptorTest(){
//简单分页模型 current:第几页 size:显示几条数据
//底层逻辑就是使用Limit分页的公式 (index-1)*pageSize
        Page<User> page = new Page<>(1,3);
//条件构造器Wrapper目前没有就写null
        userMapper.selectPage(page,null);
    }

Page对象常用方法

@Test
    public void PaginationInnerInterceptorTest2(){
//简单分页模型 current:第几页 size:显示几条数据
//底层逻辑就是使用Limit分页的公式 (index-1)*pageSize
        Page<User> page = new Page<>(2,3);
//条件构造器Wrapper目前没有就写null
        userMapper.selectPage(page,null);
//获取记录
        List<User> users = page.getRecords();
        users.forEach(user -> System.out.println(user));
        System.out.println(page.getPages()); //获取总页数
        System.out.println(page.getTotal()); //获取总数据量
        System.out.println(page.hasNext());//是否有下一页
        System.out.println(page.hasPrevious());//是否有上一页
    }

 

 逻辑删除

在企业中对于删除,一般情况下是不会真正的把数据删除掉的,而是会进行 逻辑删除
所以大家会发现一些系统,管理员可以看到已经删除的用户信息,实际上这就是一种逻辑删除,
也就是根据数据表中的类似于: deleted 的属性来标记用户删除,而并非真正删除。
逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
就是将删除delete语句改成了修改语句一般是专门一个字段用来做为是否被删除的判断

条件构造器 

MyBatis-Plus 提供了强大的条件构造器。通过条件构造器可以写一些复杂的 SQL 语句,从而提高
开发效率。
查询 mybatisPlus 源码可以看到,条件构造器 wrapper 继承情况
Wrapper :条件构造器,最顶端的一个类
        AbstractWrapper:用于 sql 语句条件的封装,主要是封装 where 条件
                QueryWrapper:查询条件封装(一般删除的条件也使用QueryWrapper
                UpdateWrapper:更新条件封装
                AbstractLambdaWrapper:具有Lambda 语法的条件封装
                        LambdaQueryWrapper:具有Lambda语法查询条件封装
                        LambdaUpdateWrapper:具有Lambda语法更新条件封装
所有的条件使用方法,在官网中有很详细的介绍
具体地址: https://www.baomidou.com/pages/10c804/#abstractwrapper

 QueryWrapper

我这里 查询username不为空的用户,并且年龄大于10岁

比较用的.ge()  这是大于等于

还有许多比较方法

// 查询名字为chen的用户

 

// 查询年龄18~25岁之间的用户

 

// 查询年龄大于等于25岁的用户

// 模糊查询:查询名字不包含a的用户,反之like就是包含

 

//模糊查询:包含左侧或者右侧具体内容

子查询 

 lambda表达式执行条件

QueryWrapper 中有 and 或者 or 这样的方法,要注意的是默认都是通过 and 来进行连接条件,
但是如果主动调用 or 方法,将会改变,还有一点如果 and 或者 or 表达式时中出现 lambda 表达式,
将会改变条件的优先级,先来执行 lambda 表达式的条件

condition

我们在写项目的时候,所有的条件都是由用户进行传递的,那么有的时候就无法避免参数出现空
null 的情况,所以我们应该要做一些判断,其实很多方法都提供了 boolean condition 这个参
数,表示该条件 是否 加入最后生成的 sql 中,也就是可以通过它来进行判断

 

 QueryWrapper执行修改和删除操作

//修改用户id为24的username为jack

 

 

UpdateWrapper 

继承自 AbstractWrapper , 自身的内部属性 entity 也用于生成 where 条件
可以通过 set 方法来进行修改
//修改年龄大于等于10,并且username为xiao的用户role为 0

 ​​​​

LambdaQueryWrapper&LambdaUpdateWrapper 

它们两个的主要目的是为了防止我们在编写的时候,字段名称编写错误,我们可以直接通过
Lambda 的方式来直接获取指定字段对应的实体类对应的名称
LambdaQueryWrapper 查询
LambdaUpdateWrapper 修改
//修改年龄大于10,并且name为xiao的用户role为 1

我的所有测试代码
package com.cqh;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cqh.entity.User;
import com.cqh.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

//查询全部
    @Test
    public void test01(){

        List<User> users = userMapper.selectList(null);
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
//插入数据
    @Test
    public void test02(){
        User user1 = new User();
        user1.setUsername("chen1");
        user1.setPassword("123456");
        user1.setAge(18);
        user1.setRole("1");
        user1.setSex(1);

        int insert = userMapper.insert(user1);
        System.out.println("insert = " + insert);
        System.out.println("id = " + user1.getId());

    }


    //根据map删除
    @Test
    public void deleteTest(){
        Map<String,Object> map = new HashMap<>();
        map.put("username","xiaoMin");
        map.put("age",11);
        int num = userMapper.deleteByMap(map);
        System.out.println(num);
    }


//根据多个id进行批量删除
    @Test
    public void deleteTest2(){
        ArrayList<Integer> ids = new ArrayList<>();
        ids.add(15);
        ids.add(17);
        int num = userMapper.deleteBatchIds(ids);
        System.out.println(num);
    }


    //根据多个条件进行删除
    @Test
    public void deleteTest3(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username","a3");
        userQueryWrapper.eq("sex",1);
        int num = userMapper.delete(userQueryWrapper);
        System.out.println(num);
    }


    //根据id修改
    @Test
    public void updateTest(){
        User user = new User();
        user.setId(6);
        user.setUsername("李四");
        int num = userMapper.updateById(user);
        System.out.println(num);
    }


    //根据Map中传递的条件进行查询
    @Test
    public void selectTest(){
        Map<String,Object> map = new HashMap<>();
        map.put("id",6);
        map.put("username","李四");
        List<User> users = userMapper.selectByMap(map);
        users.forEach(user -> System.out.println(user));
    }

    @Test
    public void selectByNameTest(){
        List<User> users = userMapper.selectByName("李四");
        users.forEach(user -> System.out.println(user));
    }


    @Test
    public void PaginationInnerInterceptorTest(){
//简单分页模型 current:第几页 size:显示几条数据
//底层逻辑就是使用Limit分页的公式 (index-1)*pageSize
        Page<User> page = new Page<>(1,3);
//条件构造器Wrapper目前没有就写null
        userMapper.selectPage(page,null);
    }



    @Test
    public void PaginationInnerInterceptorTest2(){
//简单分页模型 current:第几页 size:显示几条数据
//底层逻辑就是使用Limit分页的公式 (index-1)*pageSize
        Page<User> page = new Page<>(2,3);
//条件构造器Wrapper目前没有就写null
        userMapper.selectPage(page,null);
//获取记录
        List<User> users = page.getRecords();
        users.forEach(user -> System.out.println(user));
        System.out.println(page.getPages()); //获取总页数
        System.out.println(page.getTotal()); //获取总数据量
        System.out.println(page.hasNext());//是否有下一页
        System.out.println(page.hasPrevious());//是否有上一页
    }


    // 查询username不为空的用户,并且年龄大于10岁
    @Test
  public void selectTest1(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("username")
                .ge("age",10);
        userMapper.selectList(wrapper).forEach(System.out::println);//类似于map传入条件
    }




    // 查询名字为chen的用户
    @Test
   public void selectTest2(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username","chen");
        User user = userMapper.selectOne(wrapper);//类似于map传入条件
        System.out.println(user);
    }


    // 查询年龄18~25岁之间的用户
    @Test
   public void selectTest3(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age",18,25);
        userMapper.selectList(wrapper).forEach(System.out::println);//类似于map传入条件
    }


    // 查询年龄大于等于25岁的用户
    @Test
   public void selectTest4(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.ge("age",25);
        userMapper.selectList(wrapper).forEach(System.out::println);//类似于map传入条件
    }

    // 模糊查询:查询名字不包含a的用户,反之like就是包含
    @Test
   public void selectTest5(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.notLike("username","a");
        userMapper.selectList(wrapper).forEach(System.out::println);//类似于map传入条件
    }


    //模糊查询:包含左侧或者右侧具体内容
    @Test
   public void selectTest6(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
    // 模糊查询:查询名字不包含qf的用户,反之like就是包含
    // likeLeft和likeRight
    // 左右就是 %在左或者在右
    // 以下就是 a% 相当于以a开头的名字
        wrapper.likeRight("username","a");

        userMapper.selectList(wrapper).forEach(System.out::println);//类似于map传入条件
    }


    //通过子查询,查询id等于6的用户信息,此方法也可以进行表关联查询
    @Test
   public void selectTest7(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        wrapper.inSql("id","select id from tb_user where id=6");
        userMapper.selectObjs(wrapper).forEach(System.out::println);
    }

    // 查询用户名中包含a并且年龄大于29或者crateTime为空的用户
    @Test
   public void selectTest8(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("username","a")
                .and(w->w.gt("age",26).or().isNull("createTime"));
        userMapper.selectList(wrapper).forEach(System.out::println);
    }


    // 模糊查询:查询名字包含a的用户,并且按照age升序排序,注意参数不能为空
    @Test
   public void selectTest9(){
    //假设用户传递参数
        String username = "a";
        Integer age = 1;
        //先判断条件是否符合,符合才会组合到SQL语句中
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(username),"username",username)
                .orderByAsc(age != null,"age");
        userMapper.selectList(wrapper).forEach(System.out::println);//类似于map传入条件
    }
    //修改用户id为24的username为jack
    @Test
   public void updateTest1(){
       // QueryWrapper<User> wrapper = new QueryWrapper<>();
       // wrapper.eq("id",24);
        User user = new User();
        user.setUsername("jack");
       // userMapper.update(user,wrapper);
        userMapper.update(user,new QueryWrapper<User>().eq("id",24));
    }


    //删除username为jack的用户
    @Test
   public void deleteTest1(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username","jack");
        userMapper.delete(wrapper);
    }


    //修改年龄大于10,并且username为xiao的用户role为 0
    @Test
   public void updateTest2(){
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.gt("age",10)
                .eq("username","xiao")
                .set("role","0");
//无需传递user对象,直接赋值为null
        userMapper.update(null,wrapper);
    }


    @Test
   public void selectTest10(){
//假设用户传递参数
        String username = "a";
        Integer age = null;
//LambdaQueryWrapper就是为了防止我们写错字段,可以直接通过Lambda的方式来直接获取指定字段对应的实体类对应的名称
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(username),User::getUsername,username)
                .orderByAsc(age != null,User::getAge);
        userMapper.selectList(wrapper).forEach(System.out::println);//类似于map传入条件
    }

    //修改年龄大于10,并且name为xiao的用户role为 1
    @Test
   public void updateTest3(){
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.gt(User::getAge,10)
                .eq(User::getUsername,"xiao")
                .set(User::getRole,"1");
//无需传递user对象,直接赋值为null
        userMapper.update(null,wrapper);
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1300018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle(2-12)User-Managed Complete Recovery

文章目录 一、基础知识1、Media Recovery 介质恢复2、Recovery Steps 恢复步骤3、恢复4、Recovery in ARCHIVELOG 在ARCHIVELOG中恢复5、Complete Recovery完全恢复6、CR in ARCHIVELOG Mode 归档日志模式下的完全恢复7、Determine Files Need Recovery确定需要恢复的文件8、Ab…

JDK8新特性:Lambda表达式规则及用法,方法引用

目录 Lambda表达式是JDK8新增的一种语法格式 1.作用 2.用法规则&#xff1a; 3.方法引用 Lambda表达式是JDK8新增的一种语法格式 1.作用 简化匿名内部类的代码写法 Lambad用法前提&#xff1a;只能简化函数式接口&#xff08;一般加有Funcationallnterface&#xff09;&a…

2023年11月10日 Go生态洞察:十四年Go的成长之路

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

STL(八)(总结篇)

###以四道题来总结 题号:lanqiao OJ 3226 1.宝藏排序II ### 这道题主要考察sort,非常简单输出就是升序不需要自定义比较函数 #include<bits/stdc.h> using namespace std; const int N1e55; //这里用int就足够了不需要开long long int a[N]; int main(){ios::sync_with…

TCP的滑动窗口机制

网络的错误检测和补偿机制非常复杂。 一、等待超时时间&#xff08;返回ACK号的等待时间&#xff09; 当网络繁忙时会发生拥塞&#xff0c;ACK号的返回变慢&#xff0c;较短的等待时间会导致频繁的数据重传&#xff0c;导致本就拥塞的网络雪上加霜。如果等待时间过长&#xf…

查看mysql是否开启远程端口

这个命令&#xff1a; sudo netstat -tlnp | grep mysqld如果是 就说明只开启了本地的&#xff0c;要更改这个设置&#xff0c;你需要编辑 MySQL 的配置文件&#xff0c;并确保 bind-address 设置为 0.0.0.0。打开 MySQL 的配置文件&#xff08;通常是 /etc/mysql/mysql.conf…

二叉排序树的判断(二叉树的顺序存储):2022年408算法题

对于采用顺序存储方式保存的二叉树&#xff0c;根结点保存在SqBiTNode[0]中&#xff1b;当某结点保存SqBiTNode[i]中时&#xff0c;若有左孩子&#xff0c;则其值保存在SqBiTNode [2i1]中&#xff1b;若有右孩子&#xff0c;则其值保存在SqBiTNode[2i2]中&#xff1b;若有双亲结…

SD之lora训练

目录 为什么要训练自己的模型 SD模型微调方法 准备素材 1 确定要训练的LoRA类型 2 图片收集 3 图片预处理 4 图片标注 安装Koyha_ss 训练lora 1.准备参数和环境 2.启动训练 使用模型 1 拷贝训练过的lora模型 2 启动SD WebUI进行图像生成 为什么要训练自己的模型 …

来聊聊java8的数值流

简介 java8为我提供的简单快捷的数值流计算API&#xff0c;本文就基于几个常见的场景介绍一下数值流API的使用。 基础示例 我们以一个食物热量计算的功能展开演示&#xff0c;如下所示&#xff0c;可以看到Dish类它记录了每一个食物的名称、热量、类型等信息: public class…

百科词条可以删除吗?如何删除自己的百度百科?

近日&#xff0c;小马识途营销顾问接到不少客户删除自己百科词条的咨询&#xff0c;有不少人自己并没有去建立百科词条&#xff0c;但是网上已经有了&#xff0c;有的信息不正确&#xff0c;甚至有的信息是负能量的&#xff0c;对当事人自己造成一定的困扰&#xff0c;所以寻求…

【Proteus仿真】【51单片机】光照强度检测系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使共阴数码管&#xff0c;PCF8591 ADC模块、光敏传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;数码管显示光传感器采集光照强度值&#xff…

在线测试http接口,为您解析最佳测试方法

您是否正在寻找一种方便、高效且可靠的方法来测试您的http接口&#xff1f;在这篇文章中&#xff0c;我们将为您介绍在线测试http接口的最佳方法&#xff0c;帮助您确保您的接口在各种情况下都能正常运行。 什么是http接口&#xff1f; 在开始介绍如何测试http接口之前&#x…

json精讲

本文介绍json的规范及javascript和java对数据的交换读取 1. json介绍1.1 json简介1.2为什么使用 JSON&#xff1f; 2. json规范2.1基础规范2.2 key值为-字符串、数字、布尔值2.3 key值为对象Object2.4 key值为数组2.5 json本身就是一个数组 3.javascript操作json3.1 javascript…

git 本地有改动,远程也有改动,且文件是自动生成的配置文件

在改动过的地方 文件是.lock文件&#xff0c;自动生成的。想切到远程的分支&#xff0c;但是远程的分支也有改动过。这时候就要解决冲突&#xff0c;因为这是两个分支&#xff0c;代码都是不一样的&#xff0c;要先把这改动的代码提交在本地或者提交在本分支的远程才可以切到其…

freeswitch webrtc video_demo客户端进行MCU的视频会议

系统环境 一、编译服务器和加载模块 二、下载编译指定版本video_demo 三、配置verto.conf.xml 1.修改配置文件 2.重新启动 四、MCU通话测试 1.如何使用video_demo 2.测试结果 五、MCU的通话原理及音频/视频/布局/管理员等参数配置 附录 freeswitch微信交流群 系统环境 lsb_rel…

lv11 嵌入式开发 IIC(下) 20

目录 1 Exynos4412下IIC控制器介绍 1.1 总览 1.2 特征 1.3 工作框图 1.4 其他内容介绍 1.5 四种工作模式寄存器流程 2 IIC寄存器详解 2.1 概述 2.2 控制寄存器 2.3 状态寄存器 2.4 地址寄存器 2.5 数据寄存器 2.6 其他寄存器 3 MPU06050 3.1 简介 3.2 MPU6050主…

【已解决】解决UbuntuKali无法进行SSH远程连接

目录 Ubuntu20.04配置SSH远程连接Kali Linux配置SSH远程连接 Ubuntu20.04配置SSH远程连接 首先更新安装包 sudo apt-get update 下载SSH服务 sudo apt install openssh-server 查看SSH服务 service ssh status 打开 /etc/ssh/sshd_config文件修改配置文件 将PermitRootLog…

智能优化算法应用:基于郊狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于郊狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于郊狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.郊狼算法4.实验参数设定5.算法结果6.参考文献7.MA…

思科最新版Cisco Packet Tracer 8.2.1安装

思科最新版Cisco Packet Tracer 8.2.1安装 一. 注册并登录CISCO账号二. 下载 Cisco Packet Tracer 8.2.1三. 安装四. 汉化五. cisco packet tracer教学文档六. 正常使用图 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新…

【数据结构第 6 章 ③】- 用 C 语言实现邻接表并简单介绍十字链表和邻接多重表

目录 一、邻接表 1.1 - ALGraph.h 1.2 - ALGraph.c 1.3 - Test.c 二、十字链表 三、邻接多重表 一、邻接表 邻接表&#xff08;Adjacency List&#xff09;是图的一种链式存储结构。在邻接表中&#xff0c;对图中每个顶点建立一个单链表&#xff0c;第 i 个单链表中的结…