MyBatis Mapper XML檔案詳解
MyBatis 的真正強大在於它的對映語句,也是它的魔力所在。由於它的異常強大,對映器的 XML 檔案就顯得相對簡單。如果拿它跟具有相同功能的 JDBC 程式碼進行對比,你會立即發現省掉了將近 95% 的程式碼。MyBatis 就是針對 SQL 構建的,並且比普通的方法做的更好。
1、select(查詢)
查詢語句是 MyBatis 中最常用的元素之一,光能把資料存到資料庫中價值並不大,如果還能重新取出來才有用,多數應用也都是查詢比修改要頻繁。對每個插入、更新或刪除操作,通常對應多個查詢操作。這是 MyBatis 的基本原則之一,也是將焦點和努力放到查詢和結果對映的原因。簡單查詢的 select 元素是非常簡單的。比如:
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
這個語句被稱作 selectPerson,接受一個 int(或 Integer)型別的引數,並返回一個 HashMap 型別的物件,其中的鍵是列名,值便是結果行中的對應值。
注意引數符號: #{id}
這就告訴 MyBatis 建立一個預處理語句引數,通過 JDBC,這樣的一個引數在 SQL 中會由一個"?"來標識,並被傳遞到一個新的預處理語句中,就像這樣:
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
當然,這需要很多單獨的 JDBC 的程式碼來提取結果並將它們對映到物件例項中,這就是 MyBatis 節省你時間的地方。
select 元素有很多屬性允許你配置,來決定每條語句的作用細節:
2、Sql
這個元素可以被用來定義可重用的 SQL 程式碼段,可以包含在其他語句中。它可以被靜態地(在載入引數) 引數化. 不同的屬性值通過包含的例項變化.,比如:
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
這個 SQL 片段可以被包含在其他語句中,例如:
<select id="selectUsers" resultType="map">
select
<include refid="userColumns"><property name="alias" value="t1"/></include>,
<include refid="userColumns"><property name="alias" value="t2"/></include>
from some_table t1
cross join some_table t2
</select>
屬性值可以用於包含的refid屬性或者包含的字句裡面的屬性值,例如:
<sql id="sometable">
${prefix}Table
</sql>
<sql id="someinclude">
from
<include refid="${include_target}"/>
</sql>
<select id="select" resultType="map">
select
field1, field2, field3
<include refid="someinclude">
<property name="prefix" value="Some"/>
<property name="include_target" value="sometable"/>
</include>
</select>
3、引數(Parameters)
前面的所有語句中你所見到的都是簡單引數的例子,實際上引數是 MyBatis 非常強大的元素,對於簡單的做法,大概 90% 的情況引數都很少,比如:
<select id="selectUsers" resultType="User">
select id, username, password
from users
where id = #{id}
</select>
上面的這個示例說明了一個非常簡單的命名引數對映。引數型別被設定為 int,這樣這個引數就可以被設定成任何內容。原生的型別或簡單資料型別(比如整型和字串)因為沒有相關屬性,它會完全用引數值來替代。然而,如果傳入一個複雜的物件,行為就會有一點不同了。比如:
<insert id="insertUser" parameterType="User">
insert into users (id, username, password)
values (#{id}, #{username}, #{password})
</insert>
如果 User 型別的引數物件傳遞到了語句中,id、username 和 password 屬性將會被查詢,然後將它們的值傳入預處理語句的引數中。
4、多引數傳遞
MyBatis中的對映語句有一個parameterType屬性來制定輸入引數的型別。如果我們想給對映語句傳入多個引數的話,我們可以將所有的輸入引數放到HashMap中,將HashMap傳遞給對映語句。MyBatis 還提供了另外一種傳遞多個輸入引數給對映語句的方法。假設我們想通過給定的name和email資訊查詢學生資訊,定義查詢介面如下:
Public interface StudentMapper
{
List<Student> findAllStudentsByNameEmail(String name, String email);
}
MyBatis 支援將多個輸入引數傳遞給對映語句,並以#{param}的語法形式引用它們:
<select id="findAllStudentsByNameEmail" resultMap="StudentResult">
select stud_id, name,email, phone from Students
where name=#{param1} and email=#{param2}
</select>
這裡#{param1}引用第一個引數name,而#{param2}引用了第二個引數email
還可以使用 @Param 註解來給引數命名,定義查詢介面如下:
Public interface StudentMapper
{
List<Student> findAllStudentsByNameEmail(@Param("name") String name, @Param("email") String email);
}
MyBatis 配置檔案可以直接使用命名的引數,如下配置:
<select id="findAllStudentsByNameEmail" resultMap="StudentResult">
select stud_id, name,email, phone from Students
where name=#{name} and email=#{email}
</select>