亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

解析Mybatis判斷表達式源碼分析

2024-07-14 08:42:32
字體:
來源:轉載
供稿:網友

在我們開發過程中用 Mybatis 經常會用到下面的例子

Mapper如下

Map<String ,String > testArray(@Param("array") String [] array);

XMl中的sql如下

<select id="testArray" resultType="map">  select * from t_ams_ac_pmt_dtl where cpt_pro=#{cptProp}  <if test="array!=null and array != '' ">    and cpt_pro=#{cptProp}  </if></select>

剛看上面的代碼會覺得數組怎么能和空字符串進行一起比較呢,一開始會覺得這個代碼運行起來絕對報錯,但是寫單元測試運行了一遍發現成功運行了。因此想是不是 Mybatis 在內部對數組類型的數據進行了封裝。于是有了這一次的源碼解析之旅。上網查了查發現 Mybatis 解析使用了 OGNL 。至于什么是 OGNL 摘抄了百度百科中的一段話

OGNL是Object-Graph Navigation Language的縮寫,它是一種功能強大的表達式語言,通過它簡單一致的表達式語法,可以存取對象的任意屬性,調用對象的方法,遍歷整個對象的結構圖,實現字段類型轉化等功能。它使用相同的表達式去存取對象的屬性。這樣可以更好的取得數據。

單元測試類如下

@Test  public void testArray(){    SqlSession sqlSession = sqlSessionFactory.openSession();    TBapCheckPtsTranscdMapper mapper = sqlSession.getMapper(TBapCheckPtsTranscdMapper.class);    String str= "1,2,3";    String [] strings = str.split(",");    mapper.testArray(strings);  }

首先我們先來看一下 DynamicSqlSource 這個類,這個類中有個方法如下

@Override public BoundSql getBoundSql(Object parameterObject) {  DynamicContext context = new DynamicContext(configuration, parameterObject);  rootSqlNode.apply(context);  SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);  Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();  SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());  BoundSql boundSql = sqlSource.getBoundSql(parameterObject);  for (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {   boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());  }  return boundSql; }

其中

rootSqlNode.apply(context);

這段代碼對SQL進行了動態的拼接,然后點進去看一下

@Override public boolean apply(DynamicContext context) {  for (SqlNode sqlNode : contents) {   sqlNode.apply(context);  }  return true; }

這里的SQL拼接運用了 組合模式 不同的 sqlNode 調用的方法不一樣,但是最后的想要結果都是一樣的:拼接SQL。例如我們第一次進 apply 這個方法中的時候他跳轉到了

StaticTextSqlNode 這個類中調用了下面的方法

@Override public boolean apply(DynamicContext context) {  context.appendSql(text);  return true; }

直接將SQL拼接為

select * from t_ams_ac_pmt_dtl where cpt_pro=#{cptProp}

然后我們第二次循環執行發現它跳轉到了 IfSqlNode 這個類中,這是標簽為 <if> 的判斷類,

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

在解析語句中傳了兩個參數進去

evaluator.evaluateBoolean(test, context.getBindings())

test :就是要解析的表達式,在此場景下就是 array!=null and array != ''
context.getBindings() :獲得的是一個Map,其中存儲了參數 array 的所對應的值,如下所示

image

然后接下來就到了 OGNL 解析表達式了,發現最后到了 ASTNotEq 這類中

protected Object getValueBody(OgnlContext context, Object source) throws OgnlException {    Object v1 = this._children[0].getValue(context, source);    Object v2 = this._children[1].getValue(context, source);    return OgnlOps.equal(v1, v2) ? Boolean.FALSE : Boolean.TRUE;  }

這里解析分為了兩步進行解析,上面的表達式為 array!=null and array != '' 那么他會根據and 進行分組將其放入 Node 數組中。

Node[0] : array!=nullNode[1] : array != ''

然后這里面的兩個參數 v1 和 v2 分別為左邊和右邊的參數,此時先解析 Node[0] 中的參數

  • v1 :就是參數 array 對應的數組的值
  • v2 :就是null

此時到這應該就知道為什么 String 數組為什么能和空字符串進行比較了,因為他將數組轉化為了 Object 然后用自己寫的 equal 方法進行比較。然后進去他寫的 equal 方法中看了以后發現他對數組比較是特殊的。

  • 如果左邊是數組右邊是字符串:兩個都轉換為 Object 然后進行 v1.getClass()==v2.getClass() 判斷
  • 如果左邊是數組右邊也是數組:先判斷兩個數組的長度是否相同,如果相同,那么循環遍歷兩個數組進行里面的值的比較

總結

以上所述是小編給大家介紹的解析Mybatis判斷表達式源碼分析,希望對大家有所幫助,如果大家有任何歡迎給我留言,小編會及時回復大家的!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久中文久久字幕| 在线观看国产成人av片| 2024亚洲男人天堂| 色综合视频一区中文字幕| 欧美性在线观看| 国产免费观看久久黄| 日本亚洲精品在线观看| 亚洲精品网址在线观看| 成人午夜激情网| 亚洲天堂av图片| 欧美男插女视频| 中文字幕欧美精品在线| 欧美午夜视频一区二区| 国产日韩欧美91| 欧美激情三级免费| 日韩精品极品视频| 国产一区av在线| 日韩免费看的电影电视剧大全| 亚洲国产精品人人爽夜夜爽| 欧美不卡视频一区发布| 欧美大成色www永久网站婷| 国产精品十八以下禁看| 一道本无吗dⅴd在线播放一区| 97人人模人人爽人人喊中文字| 91人人爽人人爽人人精88v| 亚洲高清久久久久久| 亚洲欧美国产精品专区久久| 精品国产乱码久久久久久婷婷| 欧美成人精品影院| 国产精品永久免费| 欧美国产精品日韩| 亚洲社区在线观看| 欧美日韩人人澡狠狠躁视频| 久久久久久网站| 中文字幕不卡在线视频极品| 日韩美女av在线| 久久69精品久久久久久国产越南| 亚洲欧美日韩精品| 亚洲精品按摩视频| 少妇高潮 亚洲精品| 精品视频久久久| 亚洲人成网站777色婷婷| 日韩在线免费高清视频| 中文字幕在线观看日韩| 91免费国产网站| 日韩一级裸体免费视频| 精品电影在线观看| 日韩视频第一页| 亚洲成色999久久网站| 日韩欧美亚洲范冰冰与中字| 亚洲品质视频自拍网| 成人av色在线观看| 亚洲人成欧美中文字幕| 亚洲va男人天堂| 成人午夜小视频| 亚洲精品av在线播放| 国产精品电影网站| 成人免费网视频| 欧美日韩国产在线看| 亚洲国产精品成人va在线观看| 成人激情视频在线观看| 国产一区二区三区视频| 亚洲国产日韩欧美在线动漫| 日韩电影网在线| 欧美最猛性xxxxx免费| 亚洲一区亚洲二区| 91精品视频在线| 最近2019中文免费高清视频观看www99| 日韩欧美在线视频观看| 亚洲精品久久久久国产| 亚洲精品ady| 国产精品视频色| 亚洲男人天天操| 日韩网站免费观看高清| 色偷偷88888欧美精品久久久| 午夜精品福利在线观看| 日韩视频免费观看| 欧美黑人性视频| 欧美另类xxx| 亚洲a在线播放| 亚洲国产精品久久久久秋霞不卡| 日韩激情av在线免费观看| 亚洲国产一区二区三区在线观看| 国产欧美一区二区三区在线看| 久久精品成人动漫| 综合久久五月天| 日韩中文字幕视频在线观看| 午夜精品福利视频| 精品福利在线视频| 国产视频999| 亚洲精品美女久久久久| 亚洲欧洲在线看| 91久久精品在线| 久久久久一本一区二区青青蜜月| 国产精品99久久久久久www| 欧美日韩国产一区中文午夜| 久久精品中文字幕一区| 九九久久久久久久久激情| 国产不卡av在线免费观看| 亚洲精品视频二区| 亚洲精品久久久久国产| 国产精品一区二区av影院萌芽| 亚洲国产日韩欧美在线99| 国产精品高清免费在线观看| 成人精品视频99在线观看免费| 国产精品视频区| 91精品久久久久久| 欧美成人激情视频免费观看| 久久国产精品99国产精| 欧美成人精品在线播放| 欧美成人在线网站| 亲爱的老师9免费观看全集电视剧| 亚洲福利视频二区| 欧美亚洲国产成人精品| 久久这里只有精品视频首页| 久久久精品一区二区| 欧美日韩国产在线| 日韩在线视频国产| 亚洲精品视频网上网址在线观看| 成人精品视频在线| 国产精品久久久亚洲| 国产日韩欧美中文在线播放| 亚洲精品日韩在线| 国产一区二区三区日韩欧美| 亚洲男人第一网站| 欧美性猛交xxxx富婆弯腰| 91久久精品一区| 欧洲日本亚洲国产区| 国产欧美日韩精品丝袜高跟鞋| 亚洲第一网中文字幕| 狠狠久久五月精品中文字幕| 亚洲第一免费播放区| 不用播放器成人网| 亚洲精品日韩久久久| 中文字幕亚洲无线码在线一区| 亚洲乱码国产乱码精品精天堂| 亚洲xxx自由成熟| 久久手机精品视频| 欧美日韩国内自拍| 亚洲精品白浆高清久久久久久| 亚洲欧洲国产精品| 久久亚洲一区二区三区四区五区高| 亚洲欧洲美洲在线综合| 国产精品欧美日韩一区二区| 国产精品视频网| 国产精品小说在线| 久久精品国产精品| 精品一区二区三区四区| 亚洲一区二区三区sesese| 国产精品27p| 啪一啪鲁一鲁2019在线视频| 日韩精品在线免费观看视频| 亚洲精品自拍视频| 日日噜噜噜夜夜爽亚洲精品| 青青青国产精品一区二区| 91免费视频网站| 久久不射电影网| 精品亚洲国产视频| 亚洲国产天堂久久综合| 欧美激情视频在线免费观看 欧美视频免费一| 人人爽久久涩噜噜噜网站| 91免费看片在线| 一区二区三区四区在线观看视频| 韩国一区二区电影|