国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

業(yè)務(wù)中臺如何實現(xiàn)業(yè)務(wù)的結(jié)果通知

這篇具有很好參考價值的文章主要介紹了業(yè)務(wù)中臺如何實現(xiàn)業(yè)務(wù)的結(jié)果通知。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

引子

先看個技術(shù)題吧。

下面兩段代碼,執(zhí)行testFoo,結(jié)果分別是什么?

@Test
public void testFoo() {
    foo(Arrays.asList(1, 2, 3));
}

void foo(Object... args) {
    System.out.println(args);
}
@Test
public void testFoo() {
    foo(Arrays.asList(1, 2, 3));
}

void foo(Object... args) {
    System.out.println(args);
}
void foo(List list){
    System.out.println(list);
}

?文章來源地址http://www.zghlxwxcb.cn/news/detail-621643.html

一眼看出來結(jié)果的同學(xué),恭喜你,本文內(nèi)容可以略過。

?

下面是正文。

?

springboot項目通常配合mybatisplus來做數(shù)據(jù)CRUD。

我們在查詢或更新數(shù)據(jù)的時候,有時要用到in來過濾數(shù)據(jù)。比如
SELECT * FROM emax_scbg_order WHERE order_no IN (1305679009380433922,1305405259472830465)


mybatisplus中關(guān)于in方法的使用,在傳多個字段值的時候,我們經(jīng)常搞不清是傳Array呢還是ArrayList呢?
其實,細(xì)心的同學(xué),看一下in方法的簽名定義,就明白了。

mybatisplus中有4個in方法的重載。

所有Wrapper的超類是AbstractWrapper,AbstractWrapper實現(xiàn)了Func<Children, R>接口。in方法主要在Func<Children, R>接口中定義。

業(yè)務(wù)中臺如何實現(xiàn)業(yè)務(wù)的結(jié)果通知

?

?下面是Func<Children, R>接口中in方法的4個重載:

//mybatis-plus-core-3.1.2.jar
package com.baomidou.mybatisplus.core.conditions.interfaces;

/**
 * 查詢條件封裝
 *
 * @author hubin miemie HCL
 * @since 2017-05-26
 */
@SuppressWarnings("unchecked")
public interface Func<Children, R> extends Serializable {
    /**
     * ignore
     */
    default Children in(R column, Collection<?> coll) {
        return in(true, column, coll);
    }
    
    /**
     * ignore
     */
    default Children in(R column, Object... values) {
        return in(true, column, values);
    }    

    /**
     * 字段 IN (v0, v1, ...)
     * <p>例: in("id", 1, 2, 3, 4, 5)</p>
     *
     * <li> 如果動態(tài)數(shù)組為 empty 則不會進(jìn)行 sql 拼接 </li>
     *
     * @param condition 執(zhí)行條件
     * @param column    字段
     * @param values    數(shù)據(jù)數(shù)組
     * @return children
     */
    default Children in(boolean condition, R column, Object... values) {
        return in(condition, column, Arrays.stream(Optional.ofNullable(values).orElseGet(() -> new Object[]{}))
            .collect(toList()));
    }
    
    /**
     * 字段 IN (value.get(0), value.get(1), ...)
     * <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * <li> 如果集合為 empty 則不會進(jìn)行 sql 拼接 </li>
     *
     * @param condition 執(zhí)行條件
     * @param column    字段
     * @param coll      數(shù)據(jù)集合
     * @return children
     */
    Children in(boolean condition, R column, Collection<?> coll);

}


單從方法簽名以及清晰的javadoc注釋,我們可以看到,in方法接收字段值的方式有兩種,一種是Object...,一種是Collection<?>。
■ Collection<?>不用說了,是集合,比如List<E>、Set<E>、Queuet<E>等。
■ Object...是可變長參數(shù)(可變參數(shù)),可變長參數(shù)本質(zhì)上就是一個數(shù)組,既可以接收一個或多個離散的值,也可以接收數(shù)組對象。
也就是說,in方法同時支持傳入數(shù)組和集合。當(dāng)我們?nèi)雲(yún)⑹荓ist時,調(diào)用的是重載的in(Collection<?>),其他入?yún)⒎绞絼t是調(diào)用重載的in(Object...)。由此看來,調(diào)用mybatis-plus的in時,是傳Array還是傳List?就見分曉了。

現(xiàn)在,我們來做一個假設(shè):假設(shè)這些in重載方法里沒有in(Collection<?>),只有in(Object...),那么,我們應(yīng)用程序在調(diào)用的時候,當(dāng)需要in的參數(shù)值是一個集合時,如果我們把集合直接傳給in(Object...),那就是bug。因為在可變長參數(shù)里,集合是作為一個參數(shù)值的(不是多個)。也就是說,在這種假設(shè)下,程序生成的SQL會是?SELECT * FROM table1?WHERE state?IN ('[SUCCESS,FAIL]')?,我們的程序為規(guī)避這個bug,就要先把集合轉(zhuǎn)換為數(shù)組再調(diào)用in(Object...)。顯然,這樣會給我們的開發(fā)帶來額外的工作,更糟糕的是,這樣的bug很難徹底規(guī)避。

mybatis-plus框架的研發(fā)團隊顯然意識到了這個“假設(shè)”,故而增加了重載的in(Collection<?>),毋庸置疑是非常優(yōu)秀的設(shè)計。

下面詳細(xì)列舉使用in的姿勢。

?

使用in的姿勢

??正確姿勢一(List集合):

List<Long> ids = Arrays.asList(122L,23L);;
new QueryWrapper<Driver>().lambda().in(Driver::getServiceId,ids);

?

??正確姿勢二(數(shù)組對象):

Long[] ids={1305679009380433922,1305679009380433922};
LambdaQueryWrapper<Driver> queryWrapper = new QueryWrapper<Driver>().lambda().in(Driver::getServiceId,ids);

?

??正確姿勢三(離散值):

new QueryWrapper<Driver>().lambda()
.in(Driver::getServiceId,1305679009380433922,1305679009380433922);

?

正確結(jié)果:

==>  Preparing: SELECT * FROM emax_scbg_order WHERE order_no IN (?,?)
==> Parameters: 1305679009380433922(String), 1305405259472830465(String)
<==      Total: 2

?

?

千萬別傳模棱兩可的參數(shù),這樣jvm會給你意想不到的結(jié)果。

??錯誤姿勢一:

.in(
    StringUtils.isNotBlank(vo.getOrderNumList()),
    ScbgOrder::getOrderNo,
    StringUtils.isNotBlank(vo.getOrderNumList()) ? vo.getOrderNumList().split(",") : "");

錯誤結(jié)果一:

==> Preparing: SELECT * FROM emax_scbg_order WHERE order_no IN (?)
==> Parameters: [Ljava.lang.String;@3eb6d7a9(String[])
<== Total: 0

調(diào)試程序可以看到values里的參數(shù)值:

業(yè)務(wù)中臺如何實現(xiàn)業(yè)務(wù)的結(jié)果通知

?

?

??錯誤姿勢二:

.in(StringUtils.isNotBlank(vo.getOrderNumList()),ScbgOrder::getOrderNo,"123,4566");

?錯誤結(jié)果二:

==> Preparing: SELECT * FROM emax_scbg_order WHERE order_no IN (?)
==> Parameters: 123,4566(String)
<== Total: 0

OK,那么not in怎么用呢?

在mybatisplus中,not in的用法與in是相同的。如下notIn方法簽名的截圖一看便知:

業(yè)務(wù)中臺如何實現(xiàn)業(yè)務(wù)的結(jié)果通知

話外:調(diào)用in出現(xiàn)NullPointerException,why?

下面代碼執(zhí)行到第9行時,拋出空指針異常??梢钥闯鰜?,這個in重載是public Children in(boolean condition, R column, Object... values)。開發(fā)同學(xué)疑惑:明明這個in的第一個參數(shù)判斷vo.getOprationType()是否為空了呀,為空就不執(zhí)行后面的第三個參數(shù)了,不為空才會執(zhí)行后面的邏輯呀。那么,即使vo.getOprationType()為null,也不應(yīng)該會拋空指針呀!

 1 private LambdaQueryWrapper<PayMerchantOpenFlow> getPayMerchantOpenFlowQueryWrapperByVO(PayMerchantOpenFlowDTO vo){
 2     LambdaQueryWrapper<PayMerchantOpenFlow> wrapper = new QueryWrapper<PayMerchantOpenFlow>().lambda()
 3             .eq(StringUtils.isNotBlank(vo.getMerchantCode()), PayMerchantOpenFlow::getMerchantCode,vo.getMerchantCode())
 4             .eq(null != vo.getRelationId(), PayMerchantOpenFlow::getRelationId,vo.getRelationId())
 5             .eq(StringUtils.isNotBlank(vo.getStatus()), PayMerchantOpenFlow::getStatus,vo.getStatus())
 6             .eq(StringUtils.isNotBlank(vo.getMerchantName()), PayMerchantOpenFlow::getMerchantName,vo.getMerchantName())
 7             .eq(StringUtils.isNotBlank(vo.getPayChannelCode()), PayMerchantOpenFlow::getPayChannelCode,vo.getPayChannelCode())
 8             .eq(StringUtils.isNotBlank(vo.getPayChannelName()), PayMerchantOpenFlow::getPayChannelName,vo.getPayChannelName())
 9             .in(StringUtils.isNotBlank(vo.getOprationType()), PayMerchantOpenFlow::getOprationType,vo.getOprationType().split(","))
10             .between(StringUtils.isNoneBlank(vo.getCreateTimeBegin(), vo.getCreateTimeEnd()), PayMerchantOpenFlow::getCreateTime, vo.getCreateTimeBegin() + " 00:00:01", vo.getCreateTimeEnd() + " 23:59:59")
11             .orderByDesc(PayMerchantOpenFlow::getCreateTime);
12     return wrapper;
13 }

答案是:上面的“第一個條件為true時才使用第三個參數(shù)執(zhí)行sql處理”是in方法內(nèi)部的邏輯,而不是調(diào)用方的邏輯。調(diào)用方所做的事情是把參數(shù)值傳給in方法。所以, 當(dāng)vo.getOprationType()#split時,由于vo.getOprationType()是null,所以導(dǎo)致了空指針。

話外:對比spring-data-redis,再次表揚一下mybatisplus這些優(yōu)秀的in重載

spring-data-redis中的RedisTemplate類,提供了兩個execute方法,用來允許我們執(zhí)行LUA腳本。注意到了吧?這2個execute最后那個參數(shù)的類型是Object...。所以,在使用時,小心掉坑里,千萬別直接傳List哦。

業(yè)務(wù)中臺如何實現(xiàn)業(yè)務(wù)的結(jié)果通知

?

EOF,感謝閱讀!

到了這里,關(guān)于業(yè)務(wù)中臺如何實現(xiàn)業(yè)務(wù)的結(jié)果通知的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包