日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis方法入参处理

發布時間:2023/12/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis方法入参处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1,在單個入參的情況下,mybatis不做任何處理,#{參數名} 即可,甚至連參數名都可以不需要,因為只有一個參數,或者使用 Mybatis的內置參數 _parameter。

2,多個入參:

  接口方法定義:public Employee getEmpByIdAndName(Integer id,String name);

? ? ? ?取值:#{id},#{name}

? ? ? ?mybatis拋出異常:org.apache.ibatis.binding.BindingException:Paramter ‘id‘ not found Available parameters are [1,0,param1,param2]

  原因如下:

  Myabtis會特殊處理多個參數,多個參數會被封裝成一個Map(key:param1...paramN),或者根據參數索引獲取也可以(從0開始),#{param1...paramN}就是從map中獲取指定的key的值

?

3,命名參數,明確指定多個參數被封裝成Map的可以,在方法入參上使用?@Param("id") 注解。#{id}取值id的值了。

? ? ? ? ??public Employee getEmpByIdAndName(@Param("id")Integer id,@Param("name")String name);

?

4,POJO,如果多個參數正好是我們業務邏輯的數據模型,可以直接傳入POJO,#{屬性名},即可取出POJO的屬性值了。

? ? ? ? ??public Employee getEmpByIdAndName(Employee emp);

?

5,Map<String,Object>,如果多個參數不是業務邏輯的數據模型,沒有對應的pojo,為了方便,可以傳入一個Map。#{key},取出Map中對應的值。

? ? ? ? ??public Employee getEmpByIdAndName(Map<String,Object> map);

?

6,TO,如果多個參數不是業務邏輯的數據模型,但是要經常使用(比如分頁對象),推薦編寫一個TO(Transfer Object)數據傳輸對象。

?

===============================入參為集合====================================

public Employee getEmp(@Param("id")Integer id,String lastName);

? ? ?取值:id===>#{id/param1} ? ? lastName=#{param2}

?

public Employee getEmp(Integer id,@Param("e")Employee emp);

? ? ?取值:id===>#{param1} ? ? lastName=#{param2.lastName/e.lastName}

?

###特別注意,如果單個入參的類型是為集合類型,也會特殊處理,也是把傳入的List或數組封裝在Map中key:Collection(collection),如果是List還可以使用這個key(list),如果是數組key為array

public Employee getEmpId(List<Integer> ids);

? ? ?取值:取出第一個id的值。#{list[0]}

?

============================================================================================================

Mybatis參數值的獲取

  #{}:可以獲取Map中的值或者POJO對象屬性的值;

  ${}:取值效果同上,但是有區別:

    1,#{}是以預編譯的形式,將參數設置到SQL語句中;相當于使用原生的PreparedStatement;(防止SQL注入

    2,${}是以拼接字符串的形式,將參數直接拼接在SQL語句中;(會有安全隱患)

  大多數情況下,都應該去使用#{}取值;

  比如分表:按照年份分表拆分,一年一張財務表。

  select * from ${year}_工資表,表名是沒有辦法預編譯的

  select * from emp order by ${name} ${age},排序也不支持占位符

?

  

  #{}:更為豐富的用法,可以指定參數的類型,類型如下:

    1,javaType,jdbcType,mode(存儲過程),numericScale,

? ? ? ? ? ? ? ?2,resultMap,typeHandler,jdbcTypeName,expression(未來準備支持的功能)

?

    jdbcType通常需要在某種特定的條件下被設置:

      1,在數據為null的時候,有些數據庫可能不能識別Mybatis對null的默認處理,比如Oralce環境下會報錯。

      2,JdbcType OTHER 無效類型:因為Mybatis對所有的null都映射的是原生Jdbc的OTHER類型,Oracle不能正確處理。(參見 org.apache.ibatis.type.JdbcType 枚舉類)

      3,Oracle環境下應該這樣取值:#{email,jdbcType=NULL}

    由于Mybatis的全局配置中,jdbcTypeForNull=OTHER,Oracle不支持,直接更改全局配置 jdbcTypeForNull=NULL?。(Settings標簽下配置)

?

?

===============================結合源碼,查看Mybatis如何處理入參====================================

1,首先我們的Mapper接口對象是一個代理對象(org.apache.ibatis.binding.MapperProxy<T>,它實現了java提供InvocationHandler接口)

  

?

2,被調用的Mapper代理對象的方法,被抽象成為?org.apache.ibatis.binding.MapperMethod?類型的對象,執行其 execute() 方法。它會判斷方法的是insert,update,delete還是select。

  

?

3,最后調用MapperMethod對象的 convertArgsToSqlCommandParam(args) 方法將入參轉換成一個Map。

  

?

  

? ? ?

  ①獲取每個標注了 @Param 注解的參數的param值。然后復制給name。

  ②每次解析一個參數,給map中保存一個信息(key:參數索引,value:name的值)。

    name的值:

? ? ? ? ? ? ?   標注了@param注解,注解的值。

? ? ? ? ? ? ?   沒有標注:

? ? ? ? ? ? ? ? ? ?   1,全局配置:useActualParamName(需要jdk 1.8),name=入參參數名。

? ? ? ? ? ? ? ? ? ?   2,name=map.size();相當于元素的索引。

  ③如果入參為null,直接返回null。

? ? ? ?④如果names只有一個元素,并且沒有 @Param 注解。直接names中的一個元素,直接返回。

? ? ? ?⑤如果names有多個元素或者有 @Param 注解,遍歷names,names集合的value作為key;names集合的key又作為取值的參考args[0]:args[1,"tom"],重新放入一個新的Map對象中。

    額外的將一個參數使用新的key:param1...paramN 保存到一個Map對象中

總結

以上是生活随笔為你收集整理的Mybatis方法入参处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。