欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于mybatis中test條件中單引號雙引號的問題

 更新時間:2022年01月14日 09:32:11   作者:小生小生小小生  
這篇文章主要介紹了基于mybatis中test條件中單引號雙引號的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

test條件中單引號雙引號問題

在mybatis中test判斷條件中使用單引號會報錯 通常使用雙引號

通常test后的判斷條件寫在雙引號內(nèi),但是當條件中判斷使用字符串時應(yīng)該如下方式開發(fā)

<when ?test=“channel ==null” >
<when ?test='channel =="QT"' >

具體原因

為單引號會被mybatis默認為字符類型,若為單字符可以使用單引號。否則會報錯。 

動態(tài)sql中test的一些問題

mybatis動態(tài)sql中OGNL中type=="1"和type='1'的區(qū)別

最近在mybatis中使用OGNL所遇到的坑: 一點雞肋: type=="1"和type='1'的區(qū)別

//CountryDao.java
public interface CountryDao {
? ? CountryDo getByType(@Param("type") String type);
}
//CountryManager.java
@Component("countryManager")
public class CountryManager {
? ? @Autowired
? ? private CountryDao countryDao;
? ? public CountryDo getByType(String type){
? ? ? ? return countryDao.getByType(type);
? ? }
}

mapper.xml:

//.xml
<select id="getByType" resultType="com.github.**.domain.CountryDo">
? ? <choose>
? ? ? //注意寫法`type=='0'`
? ? ? ? <when test="type == '0'">
? ? ? ? ? ? SELECT * FROM country WHERE country_id = 2
? ? ? ? </when>
? ? ? ? <otherwise>
? ? ? ? ? ? SELECT * FROM country WHERE country_id = 3;
? ? ? ? </otherwise>
? ? </choose>
</select>

測試案例:

@Test
public void getByTypeTest() throws JsonProcessingException {
? ? String type = "0";
? ? CountryDo countryDo = countryManager.getByType(type);
? ? ObjectMapper mapper = new ObjectMapper();
? ? String json = mapper.writeValueAsString(countryDo);
? ? System.out.println(json);
}

理想情況下,當type=0時返回的是country_id=2的結(jié)果

測試結(jié)果:

{"countryId":3,"country":"American Samoa","lastUpdate":"2006-02-15 04:44:00.0"}

居然返回的是country_id=3的結(jié)果

百度了才知道

原來傳值進去的是String類型,而mybatis的動態(tài)sql中的OGNL表達式不會將單引號包裹的char類型的內(nèi)容轉(zhuǎn)成String類型,并且String類型和char類型直接比較一定是不相等的。所以輸出是country_id=3的結(jié)果

解決方案

將<when test="type == '0'">換成<when test='type == "0"'>即可,即將單引號換成雙引號

0==’'問題

一個更有趣的問題,如果將mapper.xml文件內(nèi)容換成:

<select id="getByType" resultType="com.github.sijing.domain.CountryDo">
? ? <choose>
? ? ? ? <when test="0 ==''">
? ? ? ? ? ? SELECT * FROM country WHERE country_id = 2
? ? ? ? </when>
? ? ? ? <otherwise>
? ? ? ? ? ? SELECT * FROM country WHERE country_id = 3;
? ? ? ? </otherwise>
? ? </choose>
</select>

測試案例不變:

@Test
public void getByTypeTest() throws JsonProcessingException {
? ? //此時傳值已經(jīng)沒有影響了
? ? String type = "0";
? ? CountryDo countryDo = countryManager.getByType(type);
? ? ObjectMapper mapper = new ObjectMapper();
? ? String json = mapper.writeValueAsString(countryDo);
? ? System.out.println(json);
}

測試結(jié)果為:

{"countryId":2,"country":"Algeria","lastUpdate":"2006-02-15 04:44:00.0"}

怎么還是country_id=2的結(jié)果?,難道0==''??

查看mybatis源碼發(fā)現(xiàn),比如對于動態(tài)sql<if>標簽的解析:

// IfSqlNode.
@Override
?public boolean apply(DynamicContext context) {
? ?if (evaluator.evaluateBoolean(test, context.getBindings())) {
? ? ?contents.apply(context);
? ? ?return true;
? ?}
? ?return false;
?}

在evaluator.evaluateBoolean方法中:

//ExpressionEvaluator.java OGNL表達式處理
public boolean evaluateBoolean(String expression, Object parameterObject) {
? Object value = OgnlCache.getValue(expression, parameterObject);
? if (value instanceof Boolean) {
? ? return (Boolean) value;
? }
? if (value instanceof Number) {
? ? return new BigDecimal(String.valueOf(value)).compareTo(BigDecimal.ZERO) != 0;
? }
? return value != null;
}

當傳入值為0時,因為0是Number類型,所以被轉(zhuǎn)成了BigDecimal類型,并與0作比較,test的結(jié)果為true,所以返回的是country_id=2的結(jié)果,這個說法有誤。。。

再次調(diào)試,首先char ''被轉(zhuǎn)成了字符String"",大概在OgnlOps.java文件的isEqual方法中的(compareWithConversion(object1, object2) == 0),點進去發(fā)現(xiàn):

case NONNUMERIC:
? ? if ((t1 == NONNUMERIC) && (t2 == NONNUMERIC)) {
? ? ? ? if ((v1 instanceof Comparable) && v1.getClass().isAssignableFrom(v2.getClass())) {
? ? ? ? ? ? result = ((Comparable) v1).compareTo(v2);
? ? ? ? ? ? break;
? ? ? ? } else {
? ? ? ? ? ? throw new IllegalArgumentException("invalid comparison: " + v1.getClass().getName() + " and "
? ? ? ? ? ? ? ? ? ? + v2.getClass().getName());
? ? ? ? }
? ? }
? ? // else fall through
case FLOAT:
case DOUBLE:
?? ?//v1=0, v2=""
? ? double dv1 = doubleValue(v1),
? ? dv2 = doubleValue(v2);
? ? return (dv1 == dv2) ? 0 : ((dv1 < dv2) ? -1 : 1);

在doubleValue方法中:

public static double doubleValue(Object value)
? ? ? ? throws NumberFormatException
? ? {
? ? ? ? if (value == null) return 0.0;
? ? ? ? Class c = value.getClass();
? ? ? ? if (c.getSuperclass() == Number.class) return ((Number) value).doubleValue();
? ? ? ? if (c == Boolean.class) return ((Boolean) value).booleanValue() ? 1 : 0;
? ? ? ? if (c == Character.class) return ((Character) value).charValue();
? ? ? ? String s = stringValue(value, true);
? ? ? ? return (s.length() == 0) ? 0.0 : Double.parseDouble(s);
? ? }

坑坑坑!!!

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Ireport的安裝與使用教程

    Ireport的安裝與使用教程

    這篇文章主要介紹了Ireport的安裝與使用教程,需要的朋友可以參考下
    2021-10-10
  • springboot 自定義404、500錯誤提示頁面的實現(xiàn)

    springboot 自定義404、500錯誤提示頁面的實現(xiàn)

    springboot 默認已經(jīng)提供了一套處理異常的機制。在 springboot 中提供了一個名為 BasicErrorController 的類來處理 /error 請求,然后跳轉(zhuǎn)到默認顯示異常的頁面來展示異常信息,本文就詳細的介紹一下,感興趣的可以了解一下
    2021-11-11
  • MyBatis-Plus將字段修改為空值的解決方案

    MyBatis-Plus將字段修改為空值的解決方案

    這篇文章主要介紹了MyBatis-Plus將字段修改為空值的解決方案,本文給大家分享三種常用的解決方案,感興趣的朋友一起看看吧
    2023-12-12
  • Java?properties?和?yml?的區(qū)別解析

    Java?properties?和?yml?的區(qū)別解析

    properties和yml都是Spring?Boot支持的兩種配置文件,它們可以看做Spring?Boot在不同時期的兩種“產(chǎn)品”,這篇文章主要介紹了Java?properties?和?yml?的區(qū)別,需要的朋友可以參考下
    2023-02-02
  • Java sm3加密算法的實現(xiàn)

    Java sm3加密算法的實現(xiàn)

    這篇文章主要介紹了Java sm3加密算法的實現(xiàn),幫助大家更好的利用Java進行加密,感興趣的朋友可以了解下
    2020-10-10
  • java如何將一個float型數(shù)的整數(shù)部分和小數(shù)分別輸出顯示

    java如何將一個float型數(shù)的整數(shù)部分和小數(shù)分別輸出顯示

    這篇文章主要介紹了java如何將一個float型數(shù)的整數(shù)部分和小數(shù)分別輸出顯示,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • spring使用RedisTemplate操作Redis數(shù)據(jù)庫

    spring使用RedisTemplate操作Redis數(shù)據(jù)庫

    這篇文章主要介紹了spring使用RedisTemplate操作Redis數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Mybatis使用useGeneratedKeys獲取自增主鍵的方法

    Mybatis使用useGeneratedKeys獲取自增主鍵的方法

    這篇文章主要給大家介紹了關(guān)于Mybatis使用useGeneratedKeys獲取自增主鍵的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • spring如何快速穩(wěn)定解決循環(huán)依賴問題

    spring如何快速穩(wěn)定解決循環(huán)依賴問題

    這篇文章主要介紹了spring如何快速穩(wěn)定解決循環(huán)依賴問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java concurrency之AtomicReference原子類_動力節(jié)點Java學(xué)院整理

    Java concurrency之AtomicReference原子類_動力節(jié)點Java學(xué)院整理

    AtomicReference是作用是對"對象"進行原子操作。這篇文章主要介紹了Java concurrency之AtomicReference原子類,需要的朋友可以參考下
    2017-06-06

最新評論