MyBatis-Plus | 充分不必要

一、什么是 MyBatis-Plus

官网地址:点击进入

MyBatis-Plys(简称 MP)是一个 MyBatis 的增强工具,在MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

二、为什么要用 MyBatis-Plus

MP的特性:

  • 无侵入: 只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小: 启动即会自动注入基本的 CRUD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作: 通过 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、SQL、Server等多种数据库
  • 内置性能分析插件: 可输出 Sql 语句以及执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件: 提供全表 delete、update 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库

  • mysql 、mariadb 、oracle 、db2 、h2 、hsql 、sqlite 、postgresql 、sqlserver 、presto 、Gauss 、Firebird
  • Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、达梦数据库 、虚谷数据库 、人大金仓数据库 、南大通用数据库

三、测试环境

3.1.创建并初始化数据库

CREATE DATABASE TQYL_MP

CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

3.2.初始化 Spring Boot工程

  • 步骤一:

  • 步骤二:

  • 步骤三:

后面就直接next

3.3.添加依赖

 <!--简化代码的工具包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency> <!--mybatis-plus的springboot支持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency> <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>

3.4.application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/tqyl_mp?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    username: root
    password: 1234

3.5.编写 pojo

package com.tqyl.domain;

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

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "`user`")
public class User implements Serializable {
    /**
     * 主键ID
     */
    @Id
    @Column(name = "id")
    private Long id;

    /**
     * 姓名
     */
    @Column(name = "`name`")
    private String name;

    /**
     * 年龄
     */
    @Column(name = "age")
    private Integer age;

    /**
     * 邮箱
     */
    @Column(name = "email")
    private String email;

    private static final long serialVersionUID = 1L;
}

3.6.Mapper

package com.tqyl.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tqyl.domain.User;
import org.apache.ibatis.annotations.Mapper;


@Mapper
public interface UserMapper extends BaseMapper<User> {
    
}

3.7.启动类

package com.tqyl;

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

@MapperScan("com.tqyl.dao")
@SpringBootApplication
public class TqylMpApplication {
    public static void main(String[] args) {
        SpringApplication.run(TqylMpApplication.class, args);
    }
}

3.8.测试类

package com.tqyl;

import com.tqyl.dao.UserMapper;
import com.tqyl.domain.User;
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;

/**
 * @author 庭前云落
 * @Date 2020/9/15 14:17
 * @description
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class TqylTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelect(){
        System.out.println("-----------华丽的分割线------------");
       List<User> ulist = userMapper.selectList(null);
        for (User user : ulist) {
            System.out.println(user);
        }
    }
}

四、CRUD 接口

Mapper CRUD 接口

  • 通用 CURD 封装 BaseMapper 接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器
  • 泛型 T 为任意实体对象
  • 参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键
  • 对象 Wrapper 为条件构造器

1、Insert

// 插入一条记录
int insert(T entity);

TEST

  @Test
    public void testInsert(){
        User user = new User();
        user.setAge(20);
        user.setEmail("[email protected]");
        user.setName("庭前云落");
        //返回的result是受影响的行数,并不是自增后的id
        int result = userMapper.insert(user);
        System.out.println("result="+result);
        //自增后的id会回填到对象中
        System.out.println(user.getId());
    }

数据已经写入数据库,但是,id的值不正确,我们期望的是数据库自增长,实际是MP生成了 id的值,写入到了数据库。

如何设置 id 的生成策略呢?

MP 支持的 id 策略:

public enum IdType {
    //数据库ID自增  
    AUTO(0),
    //该类型为未设置主键类型
    NONE(1),
    //用户输入ID,该类型可以通过自己注册自动填充插件进行填充
    INPUT(2),
    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /*** 全局唯一ID (idWorker) */
    ID_WORKER(3),
    /*** 全局唯一ID (UUID) */
    UUID(4),
    /*** 字符串全局唯一ID (idWorker 的字符串表示) */
    ID_WORKER_STR(5);

    private final int key;

    private IdType(int key) {
        this.key = key;
    }
}

修改后的 User ID 类型:

数据插入成功:

扩展: @TableField

在MP中通过@TableField 注解可以指定字段的一些属性,常常解决的问题有2个:

1、对象中的属性名和字段名不一致的问题(非驼峰)

2、对象中的属性字段在表中不存在的问题

@TableField(value="email")//解决字段名不一致
@TableField(exist=false)//该字段在数据库表中不存在

2、UPDATE

// 根据 whereEntity 条件,更新记录
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
类型 参数名 描述
T entity 实体对象 (set 条件值,可为 null)
Wrapper<T> updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)

根据 ID 修改

// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

测试:

    @Test
    public void testUpdateById(){
        User user = new User();
        user.setId(6L);//主键
        user.setName("庭前云落的修改");

        //根据id更新,更新不为null的字段
        this.userMapper.updateById(user);
    }

根据条件更新

// 根据 whereEntity 条件,更新记录
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

测试:

    @Test
    public void testUpdate(){
        User user = new User();
        //更新的字段
        user.setAge(122);
        //更新的条件
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("id",6);

        //执行更新操作
        int result = userMapper.update(user, wrapper);
        System.out.println("result="+result);
    }

OR,通过 UpdateWrapper进行操作:

    @Test
    public void testUpdate2(){
        //更新的条件
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.eq("id",6).set("age",23);
        
        //执行更新操作
        int result = userMapper.update(null,wrapper);
        System.out.println("result="+result);
    }

3、DELETE

// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
类型 参数名 描述
Wrapper<T> wrapper 实体对象封装操作类(可以为 null)
Collection<? extends Serializable> idList 主键ID列表(不能为 null 以及 empty)
Serializable id 主键ID
Map<String, Object> columnMap 表字段 map 对象

deleteById

// 根据 ID 删除
int deleteById(Serializable id);
    @Test
    public void testDeleteById(){
        //执行删除操作
        int result = userMapper.deleteById(6L);
        System.out.println("result="+result);
    }

deleteByMap

// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
    public void testDeleteByMap(){
        HashMap<String, Object> columnMap = new HashMap<>();
        columnMap.put("age",20);
        columnMap.put("name","Jack");

        //将columnMap中的元素设置为删除的条件,多个之间为and关系
        int result = userMapper.deleteByMap(columnMap);
        System.out.println("result="+result);

    }

delete

// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
    @Test
    public void testDelete(){
        User user = new User();
        user.setAge(21);
        user.setName("Sandy");

        //将实体对象进行包装,包装为操作条件
        QueryWrapper<User> wrapper = new QueryWrapper<>(user);

        int result = userMapper.delete(wrapper);
        System.out.println("result="+result);
    }

deleteBatchlds

// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
    @Test
    public void testDeleteBatchIds(){
        //根据id集合批量删除
        int result = userMapper.deleteBatchIds(Arrays.asList(1L, 3L, 5L));
        System.out.println("result="+result);
    }

4、SELECT

// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
类型 参数名 描述
Serializable id 主键ID
Wrapper<T> queryWrapper 实体对象封装操作类(可以为 null)
Collection<? extends Serializable> idList 主键ID列表(不能为 null 以及 empty)
Map<String, Object> columnMap 表字段 map 对象
IPage<T> page 分页查询条件(可以为 RowBounds.DEFAULT)

selectById

// 根据 ID 查询
T selectById(Serializable id);
    @Test
    public void testSelectById(){
        //根据id查询数据
        User user = userMapper.selectById(2L);
        System.out.println("result="+user);
    }

selectBatchlds

// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
    @Test
    public void testSelectBatchIds() {
        //根据id集合批量查询
        List<User> ulist = userMapper.selectBatchIds(Arrays.asList(2L, 3L, 1L));
        for (User user : ulist) {
            System.out.println(user);
        }
    }

selectOne

// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    @Test
    public void testSelectOne(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name","Jone");

        //根据条件查询一条数据,如果结果超过一条会报错
        User user = userMapper.selectOne(wrapper);
        System.out.println(user);
    }

selectCount

/**
* 根据 Wrapper 条件,查询总记录数 
*
* @param queryWrapper 实体对象封装操作类(可以为 null) 
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    @Test
    public void testSelectCount(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //年龄大于23岁
        wrapper.gt("age",23);

        //根据条件查询数据条数
        Integer count = userMapper.selectCount(wrapper);
        System.out.println("count="+count);
    }

selectList

// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    @Test
    public void testSelectList(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //年龄大于23岁
        wrapper.gt("age",23);
        //根据条件查询数据
        List<User> ulist = userMapper.selectList(wrapper);
        for (User user : ulist) {
            System.out.println("user="+user);
        }
    }

selectPage

/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)           
*/
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

配置分页插件:

package com.tqyl.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 庭前云落
 * @Date 2020/9/16 9:40
 * @description
 */
@Configuration
@MapperScan("com.tqyl.dao")//设置mapper接口的扫描包
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
}

测试用例:

    @Test
    public void testSelectPage(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.gt("age",20);

        Page<User> page = new Page<>(1, 3);

        //根据条件查询数据
        IPage<User> iPage = userMapper.selectPage(page, wrapper);
        System.out.println("数据总体数:"+iPage.getTotal());
        System.out.println("总页数:"+iPage.getPages());

        List<User> ulist = iPage.getRecords();
        for (User user : ulist) {
            System.out.println("user="+user);
        }
    }

五、SQL注入器

注入器配置

全局配置 sqlInjector 用于注入 ISqlInjector 接口的子类,实现自定义方法注入

  • SQL自动注入器接口 ISqlInjector

    public interface ISqlInjector {
    
        /**
         * <p>
         * 检查SQL是否注入(已经注入过不再注入)
         * </p>
         *
         * @param builderAssistant mapper 信息
         * @param mapperClass      mapper 接口的 class 对象
         */
        void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass);
    }
    

    自定义自己的通用方法可以实现接口 ISqlInjector 也可以继承抽象类 AbstractSqlInjector 注入通用方法 SQL 语句 然后继承 BaseMapper添加到自定义方法,全局配置 sqlInjector 注入 MP会自动讲类所有方法注入到 mybatis 容器中。

六、条件构造器

说明

  • 以下出现的第一个入参 boolean condition 表示该条件是否加入最后生成的 sql 中

  • 以下代码块内的多个方法均从上往下补全个别 boolean 类型的入参,默认为 true

  • 以下方法在入参中出现的 R 为泛型,普通 wrapper 中是 String,在LambdaWrapper中是函数

    (例:Entity::getId,Entity为实体类,getId 为字段 id的 getMethodsd)

  • 以下方法入参中的R column均表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R具体类型为SFunction时项目runtime不支持eclipse自家的编译器!!!

  • 以下举例均为使用普通wrapper,入参为MapList的均以json形式表现!

  • 使用中如果入参的Map或者List,则不会加入最后生成的sql中!!!

allEq

allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
  • 全部eq(或个别 isNull)

个别参数说明:

params : key为数据库字段名,value为字段值 null2IsNull : 为true则在mapvaluenull时调用 isNull 方法,为false时则忽略valuenull

  • 例1: allEq({id:1,name:"老王",age:null})--->id = 1 and name = '老王' and age is null
  • 例2: allEq({id:1,name:"老王",age:null}, false)--->id = 1 and name = '老王'
allEq(BiPredicate<R, V> filter, Map<R, V> params)
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) 

个别参数说明:

filter:过滤函数,是否允许字段传入对比条件中

paramsnull2IsNull:同上

  • 例1: allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null})--->name = '老王' and age is null
  • 例2: allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null}, false)--->name = '老王'

测试

 @Test
    public void testAllEq() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置条件
        HashMap<String, Object> params = new HashMap<>();
        params.put("name", "Jack");
        params.put("age", 20);
        params.put("email", null);

        //SELECT * FROM tb_user WHERE password IS NULL AND name = ? AND age = ?
        wrapper.allEq(params);
        
        //SELECT * FROM tb_user WHERE name = ? AND age = ?
        wrapper.allEq(params, false);

        //SELECT * FROM tb_user WHERE name = ? AND age = ?
        wrapper.allEq(k, v)->(k.equals("name") || k.equals("age")), params);

        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    

6.1.基本比较操作

  • eq
    • 等于 =
    • 例: eq("name", "老王")--->name = '老王'
eq(R column, Object val)
eq(boolean condition, R column, Object val)
  • ne
    • 不等于 <>
    • 例: ne("name", "老王")--->name <> '老王'
ne(R column, Object val)
ne(boolean condition, R column, Object val)
  • gt
    • 大于 >
    • 例: gt("age", 18)--->age > 18
gt(R column, Object val)
gt(boolean condition, R column, Object val)
  • ge
    • 大于等于 >=
    • 例: ge("age", 18)--->age >= 18
ge(R column, Object val)
ge(boolean condition, R column, Object val)
  • lt
    • 小于 <
    • 例: lt("age", 18)--->age < 18
lt(R column, Object val)
lt(boolean condition, R column, Object val)
  • le
    • 小于等于 <=
    • 例: le("age", 18)--->age <= 18
le(R column, Object val)
le(boolean condition, R column, Object val)
  • between
    • BETWEEN 值1 AND 值2
    • 例: between("age", 18, 30)--->age between 18 and 30
between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)
  • notBetween
    • NOT BETWEEN 值1 AND 值2
    • 例: notBetween("age", 18, 30)--->age not between 18 and 30
notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
  • in
  • 字段 IN (value.get(0), value.get(1), ...)
  • 例: in("age",{1,2,3})--->age in (1,2,3)
in(R column, Collection<?> value)
in(boolean condition, R column, Collection<?> value)
  • 字段 IN (v0, v1, ...)
  • 例: in("age", 1, 2, 3)--->age in (1,2,3)
in(R column, Object... values)
in(boolean condition, R column, Object... values)
  • notIn
  • 字段 NOT IN (value.get(0), value.get(1), ...)
  • 例: notIn("age",{1,2,3})--->age not in (1,2,3)
notIn(R column, Collection<?> value)
notIn(boolean condition, R column, Collection<?> value)
  • 字段 NOT IN (v0, v1, ...)
  • 例: notIn("age", 1, 2, 3)--->age not in (1,2,3)
notIn(R column, Object... values)
notIn(boolean condition, R column, Object... values)

测试

    @Test
    public void testEq() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //SELECT id,name,age,email FROM tb_user WHERE email = ? AND age >= ? AND name IN (?,?,?)
        wrapper.eq("email", "[email protected]").ge("age", 20).in("name", "Jack", "Tom", "Sandy");
        List<User> ulist = userMapper.selectList(wrapper);
        for (User user : ulist) {
            System.out.println(ulist);
        }
    }

6.2.模糊查询

  • like
    • LIKE ' %值%'
    • 例:like("name","王") --> name like '%王%'
like(R column, Object val)
like(boolean condition, R column, Object val)
  • notLike
    • NOT LIKE '%值%'
    • 例:notLike("name","王") --> name like '%王'
notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
  • likeLeft
    • LIKE '%值'
    • 例: likeLeft("name", "王") ---> name like '%王'
likeLeft(R column, Object val)
likeLeft(boolean condition, R column, Object val)
  • likeRight
    • LIKE '值%'
    • 例:likeRight("name","王") --> name like '王%'
likeRight(R column, Object val)
likeRight(boolean condition, R column, Object val)

测试

    @Test
    public void testLike() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        // SELECT id,name,age,email FROM tb_user WHERE name LIKE ?
        // Parameters: %J%(String)

        wrapper.like("name","J");

        List<User> ulist = userMapper.selectList(wrapper);
        for (User user : ulist) {
            System.out.println(user);
        }
    }

6.3.排序

  • order By

    • 排序:ORDER BY 字段...
    • 例:orderBy(true, true, "id", "name") ---> order by id ASC,name ASC
    orderBy(boolean condition, boolean isAsc, R... columns)
    
  • orderByAsc

    • 排序:ORDER BY 字段,.... ASC
    • 例:orderByAsc("id", "name") ---> order by id ASC,name ASC
    orderByAsc(R... columns)
    orderByAsc(boolean condition, R... columns)
    
  • orderByDesc

    • 排序:ORDER BY 字段,... DESC
    • 例: orderByDesc("id", "name") ---> order by id DESC,name DESC
    orderByDesc(R... columns)
    orderByDesc(boolean condition, R... columns)
    
        @Test
        public void testOrder(){
            QueryWrapper<User> wrapper = new QueryWrapper<>();
    
            //SELECT id,user_name,name,age,email FROM tb_user ORDER BY age DESC
             wrapper.orderByDesc("age");
    
            List<User> ulist = userMapper.selectList(wrapper);
            for (User user : ulist) {
                System.out.println(user);
            }
        }
    

6.4.逻辑查询

  • or
    • 拼接 OR
    • 主动调用 or 表示紧接着下一个方法不是用 and 连接!(不调用 or 则默认为使用 and 连接)
  • and
    • AND 嵌套
    • 例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status <> '活着')
    @Test
    public void testAndOr() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //SELECT id,name,age,email FROM tb_user WHERE name = ? OR age = ?
        wrapper.eq("name", "Jone").or().eq("age", 18);
        List<User> ulist = userMapper.selectList(wrapper);
        for (User user : ulist) {
            System.out.println(ulist);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章