SpringBoot 整合 MyBatis-Plus


官網文檔地址:
  https://mp.baomidou.com/guide/

https://mybatis.plus/guide/

 

 

 

一、引入依賴 https://mvnrepository.com/

 

 

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>

 

二、配置

想要在控制台查看執行的 sql 語句,可以在 yml 文件中添加配置信息

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

 

三、代碼生成器

(1)AutoGenerator 簡介
  AutoGenerator 是 MyBatis-Plus 的代碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模塊的代碼,極大的提升了開發效率。
  與 mybatis 中的 mybatis-generator-core 類似。

(2)添加依賴

 

 

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>

 

 

 

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>

 

 

 

 

創建一個 代碼生成器。用於生成代碼。

package com.lyh.test.test_mybatis_plus;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.jupiter.api.Test;

public class TestAutoGenerate {
    @Test
    public void autoGenerate() {
        // Step1:代碼生成器
        AutoGenerator mpg = new AutoGenerator();

        // Step2:全局配置
        GlobalConfig gc = new GlobalConfig();
        // 填寫代碼生成的目錄(需要修改)
        String projectPath = "E:\\myProject\\test\\test_mybatis_plus";
        // 拼接出代碼最終輸出的目錄
        gc.setOutputDir(projectPath + "/src/main/java");
        // 配置開發者信息(可選)(需要修改)
        gc.setAuthor("lyh");
        // 配置是否打開目錄,false 為不打開(可選)
        gc.setOpen(false);
        // 實體屬性 Swagger2 注解,添加 Swagger 依賴,開啟 Swagger2 模式(可選)
        //gc.setSwagger2(true);
        // 重新生成文件時是否覆蓋,false 表示不覆蓋(可選)
        gc.setFileOverride(false);
        // 配置主鍵生成策略,此處為 ASSIGN_ID(可選)
        gc.setIdType(IdType.ASSIGN_ID);
        // 配置日期類型,此處為 ONLY_DATE(可選)
        gc.setDateType(DateType.ONLY_DATE);
        // 默認生成的 service 會有 I 前綴
        gc.setServiceName("%sService");
        mpg.setGlobalConfig(gc);

        // Step3:數據源配置(需要修改)
        DataSourceConfig dsc = new DataSourceConfig();
        // 配置數據庫 url 地址
        dsc.setUrl("jdbc:mysql://localhost:3306/testMyBatisPlus?useUnicode=true&characterEncoding=utf8");
        // dsc.setSchemaName("testMyBatisPlus"); // 可以直接在 url 中指定數據庫名
        // 配置數據庫驅動
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        // 配置數據庫連接用戶名
        dsc.setUsername("root");
        // 配置數據庫連接密碼
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // Step:4:包配置
        PackageConfig pc = new PackageConfig();
        // 配置父包名(需要修改)
        pc.setParent("com.lyh.test");
        // 配置模塊名(需要修改)
        pc.setModuleName("test_mybatis_plus");
        // 配置 entity 包名
        pc.setEntity("entity");
        // 配置 mapper 包名
        pc.setMapper("mapper");
        // 配置 service 包名
        pc.setService("service");
        // 配置 controller 包名
        pc.setController("controller");
        mpg.setPackageInfo(pc);

        // Step5:策略配置(數據庫表配置)
        StrategyConfig strategy = new StrategyConfig();
        // 指定表名(可以同時操作多個表,使用 , 隔開)(需要修改)
        strategy.setInclude("test_mybatis_plus_user");
        // 配置數據表與實體類名之間映射的策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 配置數據表的字段與實體類的屬性名之間映射的策略
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 配置 lombok 模式
        strategy.setEntityLombokModel(true);
        // 配置 rest 風格的控制器(@RestController)
        strategy.setRestControllerStyle(true);
        // 配置駝峰轉連字符
        strategy.setControllerMappingHyphenStyle(true);
        // 配置表前綴,生成實體時去除表前綴
        // 此處的表名為 test_mybatis_plus_user,模塊名為 test_mybatis_plus,去除前綴后剩下為 user。
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);

        // Step6:執行代碼生成操作
        mpg.execute();
    }
}

 

四、自動填充功能。
  使用 @TableField 注解,標注需要進行填充的字段。

/**
 * 創建時間
 */
@TableField(fill = FieldFill.INSERT)
private Date createTime;

/**
 * 最后修改時間
 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

 

package com.lyh.test.test_mybatis_plus.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

 

五、邏輯刪除

  刪除數據,可以通過物理刪除,也可以通過邏輯刪除。
  物理刪除指的是直接將數據從數據庫中刪除,不保留。
  邏輯刪除指的是修改數據的某個字段,使其表示為已刪除狀態,而非刪除數據,保留該數據在數據庫中,但是查詢時不顯示該數據(查詢時過濾掉該數據)。

  給數據表增加一個字段:is_delete,用於表示該數據是否被邏輯刪除。

步驟1: 配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig

  • 例: application.yml
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: isDelete  # 全局邏輯刪除的實體字段名(since 3.3.0,配置后可以忽略不配置步驟2)
      logic-delete-value: 1 # 邏輯已刪除值(默認為 1)
      logic-not-delete-value: 0 # 邏輯未刪除值(默認為 0)

步驟2: 實體類字段上加上@TableLogic注解

使用邏輯刪除:    可以定義一個自動填充規則,初始值為 0。0 表示未刪除, 1 表示刪除。

/**
 * 邏輯刪除(0 未刪除、1 刪除)
 */
@TableLogic(value = "0", delval = "1")
@TableField(fill = FieldFill.INSERT)
private Integer isDelete;


@Override
public void insertFill(MetaObject metaObject) {
    this.strictInsertFill(metaObject, "idDelete", Integer.class, 0);
}

 

 

六、配置分頁插件。

與 mybatis 的插件 pagehelper 用法類似。
  通過簡單的配置即可使用。
  編寫一個 配置類,內部使用 @Bean 注解將 PaginationInterceptor 交給 Spring 容器管理。

 

//Spring boot方式
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {

    // 舊版
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 設置請求的頁面大於最大頁后操作, true調回到首頁,false 繼續請求  默認false
        // paginationInterceptor.setOverflow(false);
        // 設置最大單頁限制數量,默認 500 條,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 開啟 count 的 join 優化,只針對部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
    
    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }
    
}

 

 

package com.lyh.test.test_mybatis_plus.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;

/**
 * 自定義一個配置類,mapper 掃描也可在此寫上
 */
@Configuration
@MapperScan("com.lyh.test.test_mybatis_plus.mapper")
public class Myconfig {
    /**
     * 分頁插件
     * @return 分頁插件的實例
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

 

編寫分頁代碼。
  直接 new 一個 Page 對象,對象需要傳遞兩個參數(當前頁,每頁顯示的條數)。
  調用 mybatis-plus 提供的分頁查詢方法,其會將 分頁查詢的數據封裝到 Page 對象中。

 

public interface UserMapper {//可以繼承或者不繼承BaseMapper
    /**
     * <p>
     * 查詢 : 根據state狀態查詢用戶列表,分頁顯示
     * </p>
     *
     * @param page 分頁對象,xml中可以從里面進行取值,傳遞參數 Page 即自動分頁,必須放在第一位(你可以繼承Page實現自己的分頁對象)
     * @param state 狀態
     * @return 分頁對象
     */
    IPage<User> selectPageVo(Page<?> page, Integer state);
}

 

<select id="selectPageVo" resultType="com.baomidou.cloud.entity.UserVo">
    SELECT id,name FROM user WHERE state=#{state}
</select>

 

public IPage<User> selectUserPage(Page<User> page, Integer state) {
    // 不進行 count sql 優化,解決 MP 無法自動優化 SQL 問題,這時候你需要自己查詢 count 部分
    // page.setOptimizeCountSql(false);
    // 當 total 為小於 0 或者設置 setSearchCount(false) 分頁插件不會進行 count 查詢
    // 要點!! 分頁返回的對象與傳入的對象是同一個
    return userMapper.selectPageVo(page, state);
}

 

 

@Test
public void testPage() {
    // Step1:創建一個 Page 對象
    Page<User> page = new Page<>();
    // Page<User> page = new Page<>(2, 5);
    // Step2:調用 mybatis-plus 提供的分頁查詢方法
    userService.page(page, null);
    // Step3:獲取分頁數據
    System.out.println(page.getCurrent()); // 獲取當前頁
    System.out.println(page.getTotal()); // 獲取總記錄數
    System.out.println(page.getSize()); // 獲取每頁的條數
    System.out.println(page.getRecords()); // 獲取每頁數據的集合
    System.out.println(page.getPages()); // 獲取總頁數
    System.out.println(page.hasNext()); // 是否存在下一頁
    System.out.println(page.hasPrevious()); // 是否存在上一頁
}

 

import lombok.Data;

import java.util.List;

/**
 * 分頁返回對象
 * @param <T>
 */
@Data
public class PageResult<T> {
    private Long total;
    private List<T> items;
}

 

 

 @Override
    public PageResult<Article> searchArticlePage(Integer page, Integer size) {
        IPage<Article> articleIPage = new Page<>(page,size);
        QueryWrapper<Article> articleQueryWrapper = new QueryWrapper<>();
        articleQueryWrapper.lambda().eq(Article::getIsDeleted,0);
        IPage<Article> iPage = articleMapper.selectPage(articleIPage, articleQueryWrapper);
        PageResult<Article> pageResult = new PageResult<>();
        pageResult.setItems(iPage.getRecords());
        pageResult.setTotal(iPage.getTotal());
        System.out.println("文章總數:" + pageResult.getTotal());
        return pageResult;
    }

 

 

七、mybatis-plus 實現樂觀鎖(通過 version 機制)
實現思路:
  Step1:取出記錄時,獲取當前version
  Step2:更新時,帶上這個version
  Step3:執行更新時, set version = newVersion where version = oldVersion
  Step4:如果version不對,就更新失敗

 

配置樂觀鎖插件。
  編寫一個配置類(可以與上例的分頁插件共用一個配置類),將 OptimisticLockerInterceptor 通過 @Bean 交給 Spring 管理。

/**
 * 樂觀鎖插件
 * @return 樂觀鎖插件的實例
 */
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    return new OptimisticLockerInterceptor();
}

定義一個數據庫字段 version。

CREATE TABLE test_mybatis_plus_user
(
    id BIGINT 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 '郵箱',
    create_time timestamp NULL DEFAULT NULL COMMENT '創建時間',
    update_time timestamp NULL DEFAULT NULL COMMENT '最后修改時間', 
    delete_flag tinyint(1) NULL DEFAULT NULL COMMENT '邏輯刪除(0 未刪除、1 刪除)',
    version int NULL DEFAULT NULL COMMENT '版本號(用於樂觀鎖, 默認為 1)',
    PRIMARY KEY (id)
);

 

使用 @Version 注解標注對應的實體類。
  可以通過 @TableField 進行數據自動填充。

/**
 * 版本號(用於樂觀鎖, 默認為 1)
 */
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;


@Override
public void insertFill(MetaObject metaObject) {
    this.strictInsertFill(metaObject, "version", Integer.class, 1);
}

 

八、CRUD

使用代碼生成器生成的 mapper 接口中,其繼承了 BaseMapper 接口。
  而 BaseMapper 接口中封裝了一系列 CRUD 常用操作,可以直接使用,而不用自定義 xml 與 sql 語句進行 CRUD 操作(當然根據實際開發需要,自定義 sql 還是有必要的)。

【添加數據:(增)】
    int insert(T entity);              // 插入一條記錄
注:
    T         表示任意實體類型
    entity    表示實體對象

【刪除數據:(刪)】
    int deleteById(Serializable id);    // 根據主鍵 ID 刪除
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);  // 根據 map 定義字段的條件刪除
    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); // 根據實體類定義的 條件刪除對象
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 進行批量刪除
注:
    id        表示 主鍵 ID
    columnMap 表示表字段的 map 對象
    wrapper   表示實體對象封裝操作類,可以為 null。
    idList    表示 主鍵 ID 集合(列表、數組),不能為 null 或 empty

【修改數據:(改)】
    int updateById(@Param(Constants.ENTITY) T entity); // 根據 ID 修改實體對象。
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); // 根據 updateWrapper 條件修改實體對象
注:
    update 中的 entity 為 set 條件,可以為 null。
    updateWrapper 表示實體對象封裝操作類(可以為 null,里面的 entity 用於生成 where 語句)

【查詢數據:(查)】
    T selectById(Serializable id); // 根據 主鍵 ID 查詢數據
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 進行批量查詢
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // 根據表字段條件查詢
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根據實體類封裝對象 查詢一條記錄
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢記錄的總條數
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢所有記錄(返回 entity 集合)
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢所有記錄(返回 map 集合)
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢所有記錄(但只保存第一個字段的值)
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢所有記錄(返回 entity 集合),分頁
    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢所有記錄(返回 map 集合),分頁
注:
    queryWrapper 表示實體對象封裝操作類(可以為 null)
    page 表示分頁查詢條件

 

使用 代碼生成器 生成的 service 接口中,其繼承了 IService 接口。
  IService 內部進一步封裝了 BaseMapper 接口的方法(當然也提供了更詳細的方法)。
  使用時,可以通過 生成的 mapper 類進行 CRUD 操作,也可以通過 生成的 service 的實現類進行 CRUD 操作。(當然,自定義代碼執行也可)
此處簡單介紹一下 IService 中封裝的常用方法。

【添加數據:(增)】
    default boolean save(T entity); // 調用 BaseMapper 的 insert 方法,用於添加一條數據。
    boolean saveBatch(Collection<T> entityList, int batchSize); // 批量插入數據
注:
    entityList 表示實體對象集合 
    batchSize 表示一次批量插入的數據量,默認為 1000

【添加或修改數據:(增或改)】
    boolean saveOrUpdate(T entity); // id 若存在,則修改, id 不存在則新增數據
   default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper); // 先根據條件嘗試更新,然后再執行 saveOrUpdate 操作
   boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize); // 批量插入並修改數據 

【刪除數據:(刪)】
    default boolean removeById(Serializable id); // 調用 BaseMapper 的 deleteById 方法,根據 id 刪除數據。
    default boolean removeByMap(Map<String, Object> columnMap); // 調用 BaseMapper 的 deleteByMap 方法,根據 map 定義字段的條件刪除
    default boolean remove(Wrapper<T> queryWrapper); // 調用 BaseMapper 的 delete 方法,根據實體類定義的 條件刪除對象。
    default boolean removeByIds(Collection<? extends Serializable> idList); // 用 BaseMapper 的 deleteBatchIds 方法, 進行批量刪除。
    
【修改數據:(改)】
    default boolean updateById(T entity); // 調用 BaseMapper 的 updateById 方法,根據 ID 選擇修改。
    default boolean update(T entity, Wrapper<T> updateWrapper); // 調用 BaseMapper 的 update 方法,根據 updateWrapper 條件修改實體對象。
    boolean updateBatchById(Collection<T> entityList, int batchSize); // 批量更新數據

【查找數據:(查)】
    default T getById(Serializable id); // 調用 BaseMapper 的 selectById 方法,根據 主鍵 ID 返回數據。
    default List<T> listByIds(Collection<? extends Serializable> idList); // 調用 BaseMapper 的 selectBatchIds 方法,批量查詢數據。
    default List<T> listByMap(Map<String, Object> columnMap); // 調用 BaseMapper 的 selectByMap 方法,根據表字段條件查詢
    default T getOne(Wrapper<T> queryWrapper); // 返回一條記錄(實體類保存)。
    Map<String, Object> getMap(Wrapper<T> queryWrapper); // 返回一條記錄(map 保存)。
    default int count(Wrapper<T> queryWrapper); // 根據條件返回 記錄數。
    default List<T> list(); // 返回所有數據。
    default List<T> list(Wrapper<T> queryWrapper); // 調用 BaseMapper 的 selectList 方法,查詢所有記錄(返回 entity 集合)。
    default List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper); // 調用 BaseMapper 的 selectMaps 方法,查詢所有記錄(返回 map 集合)。
    default List<Object> listObjs(); // 返回全部記錄,但只返回第一個字段的值。
    default <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper); // 調用 BaseMapper 的 selectPage 方法,分頁查詢
    default <E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper); // 調用 BaseMapper 的 selectMapsPage 方法,分頁查詢
注:
    get 用於返回一條記錄。
    list 用於返回多條記錄。
    count 用於返回記錄總數。
    page 用於分頁查詢。
    
【鏈式調用:】
    default QueryChainWrapper<T> query(); // 普通鏈式查詢
    default LambdaQueryChainWrapper<T> lambdaQuery(); // 支持 Lambda 表達式的修改
    default UpdateChainWrapper<T> update(); // 普通鏈式修改
    default LambdaUpdateChainWrapper<T> lambdaUpdate(); // 支持 Lambda 表達式的修改
注:
    query 表示查詢
    update 表示修改
    Lambda 表示內部支持 Lambda 寫法。
形如:
    query().eq("column", value).one();
    lambdaQuery().eq(Entity::getId, value).list();
    update().eq("column", value).remove();
    lambdaUpdate().eq(Entity::getId, value).update(entity);

 上面介紹的 接口方法的參數中,會出現各種 wrapper,比如 queryWrapper、updateWrapper 等。wrapper 的作用就是用於定義各種各樣的查詢條件(where)。

Wrapper  條件構造抽象類
    -- AbstractWrapper 查詢條件封裝,用於生成 sql 中的 where 語句。
        -- QueryWrapper Entity 對象封裝操作類,用於查詢。
        -- UpdateWrapper Update 條件封裝操作類,用於更新。
    -- AbstractLambdaWrapper 使用 Lambda 表達式封裝 wrapper
        -- LambdaQueryWrapper 使用 Lambda 語法封裝條件,用於查詢。
        -- LambdaUpdateWrapper 使用 Lambda 語法封裝條件,用於更新。

 常用條件

【通用條件:】
【比較大小: ( =, <>, >, >=, <, <= )】
    eq(R column, Object val); // 等價於 =,例: eq("name", "老王") ---> name = '老王'
    ne(R column, Object val); // 等價於 <>,例: ne("name", "老王") ---> name <> '老王'
    gt(R column, Object val); // 等價於 >,例: gt("name", "老王") ---> name > '老王'
    ge(R column, Object val); // 等價於 >=,例: ge("name", "老王") ---> name >= '老王'
    lt(R column, Object val); // 等價於 <,例: lt("name", "老王") ---> name < '老王'
    le(R column, Object val); // 等價於 <=,例: le("name", "老王") ---> name <= '老王'
    
【范圍:(betweennot betweeninnot in)】
   between(R column, Object val1, Object val2); // 等價於 between a and b, 例: between("age", 18, 30) ---> age between 18 and 30
   notBetween(R column, Object val1, Object val2); // 等價於 not between a and b, 例: notBetween("age", 18, 30) ---> age not between 18 and 30
   in(R column, Object... values); // 等價於 字段 IN (v0, v1, ...),例: in("age",{1,2,3}) ---> age in (1,2,3)
   notIn(R column, Object... values); // 等價於 字段 NOT IN (v0, v1, ...), 例: notIn("age",{1,2,3}) ---> age not in (1,2,3)
   inSql(R column, Object... values); // 等價於 字段 IN (sql 語句), 例: inSql("id", "select id from table where id < 3") ---> id in (select id from table where id < 3)
   notInSql(R column, Object... values); // 等價於 字段 NOT IN (sql 語句)
   
【模糊匹配:(like)】
    like(R column, Object val); // 等價於 LIKE '%值%',例: like("name", "王") ---> name like '%王%'
    notLike(R column, Object val); // 等價於 NOT LIKE '%值%',例: notLike("name", "王") ---> name not like '%王%'
    likeLeft(R column, Object val); // 等價於 LIKE '%值',例: likeLeft("name", "王") ---> name like '%王'
    likeRight(R column, Object val); // 等價於 LIKE '值%',例: likeRight("name", "王") ---> name like '王%'
    
【空值比較:(isNull、isNotNull)】
    isNull(R column); // 等價於 IS NULL,例: isNull("name") ---> name is null
    isNotNull(R column); // 等價於 IS NOT NULL,例: isNotNull("name") ---> name is not null

【分組、排序:(grouphavingorder)】
    groupBy(R... columns); // 等價於 GROUP BY 字段, ..., 例: groupBy("id", "name") ---> group by id,name
    orderByAsc(R... columns); // 等價於 ORDER BY 字段, ... ASC, 例: orderByAsc("id", "name") ---> order by id ASC,name ASC
    orderByDesc(R... columns); // 等價於 ORDER BY 字段, ... DESC, 例: orderByDesc("id", "name") ---> order by id DESC,name DESC
    having(String sqlHaving, Object... params); // 等價於 HAVING ( sql語句 ), 例: having("sum(age) > {0}", 11) ---> having sum(age) > 11

【拼接、嵌套 sql:(orand、nested、apply)】
   or(); // 等價於 a or b, 例:eq("id",1).or().eq("name","老王") ---> id = 1 or name = '老王'
   or(Consumer<Param> consumer); // 等價於 or(a or/and b),or 嵌套。例: or(i -> i.eq("name", "李白").ne("status", "活着")) ---> or (name = '李白' and status <> '活着')
   and(Consumer<Param> consumer); // 等價於 and(a or/and b),and 嵌套。例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status <> '活着')
   nested(Consumer<Param> consumer); // 等價於 (a or/and b),普通嵌套。例: nested(i -> i.eq("name", "李白").ne("status", "活着")) ---> (name = '李白' and status <> '活着')
   apply(String applySql, Object... params); // 拼接sql(若不使用 params 參數,可能存在 sql 注入),例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08") ---> date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
   last(String lastSql); // 無視優化規則直接拼接到 sql 的最后,可能存若在 sql 注入。
   exists(String existsSql); // 拼接 exists 語句。例: exists("select id from table where age = 1") ---> exists (select id from table where age = 1)
   
【QueryWrapper 條件:】
    select(String... sqlSelect); // 用於定義需要返回的字段。例: select("id", "name", "age") ---> select id, name, age
    select(Predicate<TableFieldInfo> predicate); // Lambda 表達式,過濾需要的字段。
    lambda(); // 返回一個 LambdaQueryWrapper
    
【UpdateWrapper 條件:】
    set(String column, Object val); // 用於設置 set 字段值。例: set("name", null) ---> set name = null
    etSql(String sql); // 用於設置 set 字段值。例: setSql("name = '老李頭'") ---> set name = '老李頭'
    lambda(); // 返回一個 LambdaUpdateWrapper

 

@Test
public void testQueryWrapper() {
    // Step1:創建一個 QueryWrapper 對象
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();

    // Step2: 構造查詢條件
    queryWrapper
            .select("id", "name", "age")
            .eq("age", 20)
            .like("name", "j");

    // Step3:執行查詢
    userService
            .list(queryWrapper)
            .forEach(System.out::println);
}

 

 

 https://www.bilibili.com/video/av28331070/?p=5&spm_id_from=pageDriver

https://www.cnblogs.com/liuyangfirst/tag/MybatisPlus/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM