" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

mybatis多條件in查詢的實(shí)現(xiàn)

 更新時(shí)間:2026年04月02日 10:26:40   作者:JAVA拾貝  
使用MyBatis-Plus的Lambda方法進(jìn)行查詢時(shí),遇到多條件IN查詢的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

最近碰上有個業(yè)務(wù),查詢的sql如下:

select * from table where (sku_id,batch_no) in ((#{skuId},#{batchNo}),...); 

本來也沒什么,很簡單常見的一種sql。問題是我們使用的是mybatis-plus,然后寫的時(shí)候又沒有考慮到后面的查詢條件,這里用的是mybatis-plus lambda的方式。

LambdaQueryChainWrapper<Table> query = tableService.lambdaQuery();  
query.eq(Table::getId, param.getId()); 

但是mysql-plus并沒有支持這種sql的形式,要么用apply方法自定義拼接sql,要么不采用lambda方式,將語句寫成 xml 形式。

不過,第一種方式感覺很 low,一大段 java 代碼里插入一段sql字符串,看上去就很別扭,因?yàn)橛悬c(diǎn)代碼潔癖,只能果斷放棄。

第二種改動又太大,前面那么多查詢條件,又要全部移入xml里面,同時(shí),本來已經(jīng)通過測試的篩選條件,又要重新來一遍,太懶,實(shí)在干不動了。

想想這么常見的場景,網(wǎng)上理應(yīng)有現(xiàn)成的解決方案。但不知道是搜索關(guān)鍵字不對還是確實(shí)沒有,搜了半天沒搜出來。

最后無奈,只能嘗試自己擴(kuò)展一下。

代碼

import com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper;
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import io.vavr.Tuple;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.enums.SqlKeyword.IN;
import static java.util.stream.Collectors.joining;

public class CombinationLambdaQueryChainWrapper<T> extends AbstractLambdaWrapper<T, CombinationLambdaQueryChainWrapper<T>> {

    /**
     * 查詢字段
     */
    private String sqlSelect;

    public CombinationLambdaQueryChainWrapper() {
        this(null);
    }

    public CombinationLambdaQueryChainWrapper(T entity) {
        this.entity = entity;
        this.initEntityClass();
        this.initNeed();
    }

    CombinationLambdaQueryChainWrapper(T entity, Class<T> entityClass, String sqlSelect, AtomicInteger paramNameSeq, Map<String, Object> paramNameValuePairs,
                                       MergeSegments mergeSegments) {
        this.entity = entity;
        this.paramNameSeq = paramNameSeq;
        this.paramNameValuePairs = paramNameValuePairs;
        this.expression = mergeSegments;
        this.sqlSelect = sqlSelect;
        this.entityClass = entityClass;
    }

    /**
     * <p>
     * SELECT 部分 SQL 設(shè)置
     * </p>
     *
     * @param columns 查詢字段
     */
    @SafeVarargs
    public final CombinationLambdaQueryChainWrapper<T> select(SFunction<T, ?>... columns) {
        if (ArrayUtils.isNotEmpty(columns)) {
            this.sqlSelect = this.columnsToString(columns);
        }
        return typedThis;
    }

    public CombinationLambdaQueryChainWrapper<T> select(Predicate<TableFieldInfo> predicate) {
        return select(entityClass, predicate);
    }

    /**
     * <p>
     * 過濾查詢的字段信息(主鍵除外!)
     * </p>
     * <p>
     * 例1: 只要 java 字段名以 "test" 開頭的              -> select(i -> i.getProperty().startsWith("test"))
     * 例2: 只要 java 字段屬性是 CharSequence 類型的       -> select(TableFieldInfo::isCharSequence)
     * 例3: 只要 java 字段沒有填充策略的                   -> select(i -> i.getFieldFill == FieldFill.DEFAULT)
     * 例4: 要全部字段                                   -> select(i -> true)
     * 例5: 只要主鍵字段                                 -> select(i -> false)
     * </p>
     *
     * @param predicate 過濾方式
     * @return this
     */
    public CombinationLambdaQueryChainWrapper<T> select(Class<T> entityClass, Predicate<TableFieldInfo> predicate) {
        this.entityClass = entityClass;
        this.sqlSelect = TableInfoHelper.getTableInfo(getCheckEntityClass()).chooseSelect(predicate);
        return typedThis;
    }

    @Override
    public String getSqlSelect() {
        return sqlSelect;
    }

    /**
     * <p>
     * 用于生成嵌套 sql
     * 故 sqlSelect 不向下傳遞
     * </p>
     */
    @Override
    protected CombinationLambdaQueryChainWrapper<T> instance(AtomicInteger paramNameSeq, Map<String, Object> paramNameValuePairs) {
        return new CombinationLambdaQueryChainWrapper<>(entity, entityClass, null, paramNameSeq, paramNameValuePairs, new MergeSegments());
    }

    /**
     * 組合IN查詢
     * 此處引入元組,需使用io.vavr包
     **/
    public CombinationLambdaQueryChainWrapper<T> combinationIn(boolean condition, List<Tuple> list, SFunction<T, ?>... columns) {
        Assert.isTrue(columns.length == list.get(0).arity(), "請檢查組合IN查詢參數(shù)長度");
        return doIt(condition,
                () -> StringPool.LEFT_BRACKET + columnsToString(columns) + StringPool.RIGHT_BRACKET,
                IN,
                inExpressionOfParam(list));
    }


    private ISqlSegment inExpressionOfParam(List<Tuple> list) {
        if (list.size() > 1000) {
            throw new RuntimeException("組合查詢禁止超過1000條");
        }
        List<String> result = list.stream().map(m -> StringPool.LEFT_BRACKET + m.toSeq().asJava().stream()
                .map(n -> n instanceof String ? StringPool.SINGLE_QUOTE + n + StringPool.SINGLE_QUOTE : String.valueOf(n)).collect(Collectors.joining(StringPool.COMMA)) + StringPool.RIGHT_BRACKET).collect(Collectors.toList());
        return () -> result.stream()
                .collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET));
    }

}

使用示例

productRelService.list(new CombinationLambdaQueryChainWrapper<ProductRel>().select(ProductRel::getLevelId).eq(ProductRel::getLevelId, "GBZ0555A0002").combinationIn(true, Arrays.asList(Tuple.of("91cf1c0f3b0bc46e0238dc33717dc88e", "GBZ0555A0002")), ProductRel::getProductUuid, ProductRel::getLevelId));
productRelService.list(new CombinationLambdaQueryChainWrapper<ProductRel>().combinationIn(true, Arrays.asList(Tuple.of(1L, "GBZ0555A0002")), ProductRel::getId, ProductRel::getLevelId));

到此這篇關(guān)于mybatis多條件in查詢的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)mybatis多條件in查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 整理總結(jié)Java多線程程序編寫的要點(diǎn)

    整理總結(jié)Java多線程程序編寫的要點(diǎn)

    這篇文章主要介紹了Java多線程程序編寫的要點(diǎn),包括線程的狀態(tài)控制和優(yōu)先級以及線程的通信問題等方面,非常之全面!需要的朋友可以參考下
    2016-01-01
  • 通過Java實(shí)現(xiàn)對PDF頁面的詳細(xì)設(shè)置

    通過Java實(shí)現(xiàn)對PDF頁面的詳細(xì)設(shè)置

    這篇文章主要介紹了通過Java實(shí)現(xiàn)對PDF頁面的詳細(xì)設(shè)置,下面的示例將介紹通過Java編程來對PDF頁面進(jìn)行個性化設(shè)置的方法,包括設(shè)置頁面大小、頁邊距、紙張方向、頁面旋轉(zhuǎn)等,需要的朋友可以參考下
    2019-07-07
  • java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單

    java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單

    我們給大家?guī)硪黄P(guān)于java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單的基礎(chǔ)性文章,有需要的朋友們可以學(xué)習(xí)下。
    2020-11-11
  • idea中l(wèi)ombok啟用的方法示例

    idea中l(wèi)ombok啟用的方法示例

    這篇文章主要介紹了idea中l(wèi)ombok啟用的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • spring中@RestController和@Controller的區(qū)別小結(jié)

    spring中@RestController和@Controller的區(qū)別小結(jié)

    @RestController和@Controller這兩個注解用于創(chuàng)建Web應(yīng)用程序的控制器類,那么這兩個注解有哪些區(qū)別,本文就來介紹一下,并用示例代碼說明,感興趣的可以了解一下
    2023-09-09
  • redis分布式鎖的原理及代碼實(shí)例

    redis分布式鎖的原理及代碼實(shí)例

    這篇文章主要介紹了redis分布式鎖的原理及代碼實(shí)例,Redis作為一款高性能內(nèi)存數(shù)據(jù)庫,其提供了一種非常實(shí)用的分布式鎖解決方案,可以幫助開發(fā)人員輕松地實(shí)現(xiàn)分布式鎖功能,對于分布式系統(tǒng)的開發(fā)和維護(hù),具有非常大的實(shí)用價(jià)值,需要的朋友可以參考下
    2024-01-01
  • Spring boot實(shí)現(xiàn)一個簡單的ioc(2)

    Spring boot實(shí)現(xiàn)一個簡單的ioc(2)

    這篇文章主要為大家詳細(xì)介紹了Spring boot實(shí)現(xiàn)一個簡單ioc的第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • java動態(tài)目錄樹的實(shí)現(xiàn)示例

    java動態(tài)目錄樹的實(shí)現(xiàn)示例

    在開發(fā)過程中,常常需要對目錄結(jié)構(gòu)進(jìn)行操作和展示,本文主要介紹了java動態(tài)目錄樹的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Java中MapStruct轉(zhuǎn)換實(shí)體的步驟實(shí)現(xiàn)

    Java中MapStruct轉(zhuǎn)換實(shí)體的步驟實(shí)現(xiàn)

    本文主要介紹了Java中MapStruct轉(zhuǎn)換實(shí)體的步驟實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • 詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別

    詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別

    在?Java?開發(fā)中,表達(dá)式語言是一種強(qiáng)大的工具,而SpEL?表達(dá)式與EL?表達(dá)式是我們常常遇到兩種表達(dá)式語言,下面我們就來看看它們的具體使用與區(qū)別吧
    2023-07-07

最新評論

贵港市| 玛纳斯县| 兴仁县| 武城县| 台中县| 门头沟区| 定南县| 吉安县| 漳州市| 青州市| 东明县| 米林县| 鲜城| 古交市| 嵊州市| 喀喇沁旗| 连山| 葫芦岛市| 车险| 尼勒克县| 青河县| 奉节县| 仙桃市| 博罗县| 沅陵县| 宝山区| 育儿| 大方县| 平湖市| 台北市| 共和县| 剑川县| 鄂托克旗| 都兰县| 铁岭县| 西充县| 巢湖市| 五指山市| 大英县| 唐山市| 青阳县|