" />

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

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

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

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

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

本來也沒什么,很簡(jiǎn)單常見的一種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)代碼潔癖,只能果斷放棄。

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

想想這么常見的場(chǎng)景,網(wǎng)上理應(yīng)有現(xiàn)成的解決方案。但不知道是搜索關(guān)鍵字不對(duì)還是確實(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(), "請(qǐng)檢查組合IN查詢參數(shù)長(zhǎng)度");
        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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    在開發(fā)過程中,常常需要對(duì)目錄結(jié)構(gòu)進(jìn)行操作和展示,本文主要介紹了java動(dòng)態(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ì),對(duì)大家的學(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

最新評(píng)論

富锦市| 太谷县| 饶河县| 台前县| 泸州市| 深泽县| 彭泽县| 葵青区| 府谷县| 六枝特区| 蒙城县| 罗江县| 东乡县| 互助| 广南县| 开封县| 马公市| 镇坪县| 富蕴县| 曲松县| 巫山县| 富阳市| 昭苏县| 贵溪市| 泰顺县| 安乡县| 高要市| 祥云县| 武定县| 正定县| 漳浦县| 新和县| 抚宁县| 遂溪县| 钟山县| 裕民县| 随州市| 仪陇县| 清新县| 大方县| 汕头市|