這個元素可以被用來定義可重用的 SQL 代碼段,可以包含在其他語句中。它可以被靜态地(在加載參數) 參數化. 不同的屬性值通過包含的執行個體變化. 比如:
這個 SQL 片段可以被包含在其他語句中,例如:
屬性值也可以被用在 include 元素的 refid 屬性裡(
)或 include 内部語句中(
),例如:
前面的所有語句中你所見到的都是簡單參數的例子,實際上參數是 MyBatis 非常強大的元素,對于簡單的做法,大概 90% 的情況參數都很少,比如:
上面的這個示例說明了一個非常簡單的命名參數映射。參數類型被設定為 int,這樣這個參數就可以被設定成任何内容。原生的類型或簡單資料類型(比如整型和字元串)因為沒有相關屬性,它會完全用參數值來替代。然而,如果傳入一個複雜的對象,行為就會有一點不同了。比如:
如果 User 類型的參數對象傳遞到了語句中,id、username 和 password 屬性将會被查找,然後将它們的值傳入預處理語句的參數中。
這點相對于向語句中傳參是比較好的,而且又簡單,不過參數映射的功能遠不止于此。
首先,像 MyBatis 的其他部分一樣,參數也可以指定一個特殊的資料類型。
像 MyBatis 的剩餘部分一樣,javaType 通常可以由參數對象确定,除非該對象是一個 HashMap。這時所使用的 TypeHandler 應該明确指明 javaType。
NOTE 如果一個列允許 null 值,并且會傳遞值 null 的參數,就必須要指定 JDBC Type。閱讀 PreparedStatement.setNull() 的 JavaDocs 文檔來擷取更多資訊。
為了以後定制類型處理方式,你也可以指定一個特殊的類型處理器類(或别名),比如:
盡管看起來配置變得越來越繁瑣,但實際上,很少需要去設定它們。
對于數值類型,還有一個小數保留位數的設定,來确定小數點後保留的位數。
最後,mode 屬性允許你指定 IN,OUT 或 INOUT 參數。如果參數為 OUT 或 INOUT,參數對象屬性的真實值将會被改變,就像你在擷取輸出參數時所期望的那樣。如果 mode 為 OUT(或 INOUT),而且 jdbcType 為 CURSOR(也就是 Oracle 的 REFCURSOR),你必須指定一個 resultMap 來映射結果集 ResultMap 到參數類型。要注意這裡的 javaType 屬性是可選的,如果留白并且 jdbcType 是 CURSOR,它會被自動地被設為 ResultMap。
MyBatis 也支援很多進階的資料類型,比如結構體,但是當注冊 out 參數時你必須告訴它語句類型名稱。比如(再次提示,在實際中要像這樣不能換行):
盡管所有這些選項很強大,但大多時候你隻須簡單地指定屬性名,其他的事情 MyBatis 會自己去推斷,頂多要為可能為空的列指定 jdbcType。
字元串替換
預設情況下,使用 #{} 格式的文法會導緻 MyBatis 建立 PreparedStatement 參數并安全地設定參數(就像使用 ? 一樣)。這樣做更安全,更迅速,通常也是首選做法,不過有時你就是想直接在 SQL 語句中插入一個不轉義的字元串。比如,像 ORDER BY,你可以這樣來使用:
NOTE 用這種方式接受使用者的輸入,并将其用于語句中的參數是不安全的,會導緻潛在的 SQL 注入攻擊,是以要麼不允許使用者輸入這些字段,要麼自行轉義并檢驗。