Mybatis之mapper XML 檔案

來源:互聯網
上載者:User

Mybatis之mapper XML 檔案

原文連結:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html
一、mapper XML 檔案

    MyBatis 的真正強大在於它的映射語句,也是它的魔力所在。由於它的異常強大,映射器的 XML 檔案就顯得相對簡單。如果拿它跟具有相同功能的 JDBC 代碼進行對比,你會立即發現省掉了將近 95% 的代碼。MyBatis 就是針對 SQL 構建的,並且比普通的方法做的更好。

SQL 對應檔有很少的幾個頂級元素(按照它們應該被定義的順序): cache – 給定命名空間的緩衝配置。 cache-ref – 其他命名空間緩衝配置的引用。 resultMap – 是最複雜也是最強大的元素,用來描述如何從資料庫結果集中來載入對象。 parameterMap – 已廢棄。老式風格的參數映射。內聯參數是首選,這個元素可能在將來被移除,這裡不會記錄。 sql – 可被其他語句引用的可重用語句塊。 insert – 映射插入語句 update – 映射更新語句 delete – 映射刪除語句 select – 映射查詢語句

下一部分將從語句本身開始來描述每個元素的細節。 1.1、select

    查詢語句是 MyBatis 中最常用的元素之一,光能把資料存到資料庫中價值並不大,如果還能重新取出來才有用,多數應用也都是查詢比修改要頻繁。對每個插入、更新或刪除操作,通常對應多個查詢操作。這是 MyBatis 的基本原則之一,也是將焦點和努力放到查詢和結果映射的原因。簡單查詢的 select 元素是非常簡單的。比如:

<select id="selectPerson" parameterType="int" resultType="hashmap">  SELECT * FROM PERSON WHERE ID = #{id}</select>
    這個語句被稱作 selectPerson,接受一個 int(或 Integer)類型的參數,並返回一個 HashMap 類型的對象,其中的鍵是列名,值便是結果行中的對應值
select 元素有很多屬性允許你配置,來決定每條語句的作用細節。

<select  id="selectPerson"  parameterType="int"  parameterMap="deprecated"  resultType="hashmap"  resultMap="personResultMap"  flushCache="false"  useCache="true"  timeout="10000"  fetchSize="256"  statementType="PREPARED"  resultSetType="FORWARD_ONLY">

1.2、insert,update 和 delete

資料變更語句 insert,update 和 delete 的實現非常接近:

<insert  id="insertAuthor"  parameterType="domain.blog.Author"  flushCache="true"  statementType="PREPARED"  keyProperty=""  keyColumn=""  useGeneratedKeys=""  timeout="20"><update  id="updateAuthor"  parameterType="domain.blog.Author"  flushCache="true"  statementType="PREPARED"  timeout="20"><delete  id="deleteAuthor"  parameterType="domain.blog.Author"  flushCache="true"  statementType="PREPARED"  timeout="20">

下面就是 insert,update 和 delete 語句的樣本:

<insert id="insertAuthor">  insert into Author (id,username,password,email,bio)  values (#{id},#{username},#{password},#{email},#{bio})</insert><update id="updateAuthor">  update Author set    username = #{username},    password = #{password},    email = #{email},    bio = #{bio}  where id = #{id}</update><delete id="deleteAuthor">  delete from Author where id = #{id}</delete>

   如前所述,插入語句的配置規則更加豐富,在插入語句裡面有一些額外的屬性和子項目用來處理主鍵的產生,而且有多種產生方式。

   首先,如果你的資料庫支援自動產生主鍵的欄位(比如 MySQL 和 SQL Server),那麼你可以設定 useGeneratedKeys=”true”,然後再把 keyProperty 設定到目標屬性上就OK了。例如,如果上面的 Author 表已經對 id 使用了自動產生的列類型,那麼語句可以修改為:

<insert id="insertAuthor" useGeneratedKeys="true"    keyProperty="id">  insert into Author (username,password,email,bio)  values (#{username},#{password},#{email},#{bio})</insert>
如果你的資料庫還支援多行插入, 你也可以傳入一個Authors數組或集合,並返回自動產生的主鍵
<insert id="insertAuthor" useGeneratedKeys="true"    keyProperty="id">  insert into Author (username, password, email, bio) values  <foreach item="item" collection="list" separator=",">    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})  </foreach></insert>
1.3、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>

1.4、ResultMap

    resultMap 元素是 MyBatis 中最重要最強大的元素。它就是讓你遠離 90%的需要從結果集中取出資料的 JDBC 代碼的那個東西,而且在一些情形下允許你做一些 JDBC 不支援的事情。事實上,編寫相似於對複雜語句聯合映射這些等同的代碼,也許可以跨過上千行的代碼。ResultMap 的設計就是簡單語句不需要明確的結果映射,而很多複雜語句確實需要描述它們的關係。

解決列名不匹配的一種方式:

<resultMap id="userResultMap" type="User">  <id property="id" column="user_id" />  <result property="username" column="user_name"/>  <result property="password" column="hashed_password"/></resultMap>
引用它的語句使用 resultMap 屬性就行了(注意我們去掉了 resultType 屬性)。比如:
<select id="selectUsers" resultMap="userResultMap">  select user_id, user_name, hashed_password  from some_table  where id = #{id}</select>

進階結果映射 resultMap constructor - 類在執行個體化時,用來注入結果到構造方法中 idArg - ID 參數;標記結果作為 ID 可以協助提高整體效能 arg - 注入到構造方法的一個普通結果 id – 一個 ID 結果;標記結果作為 ID 可以協助提高整體效能 result – 注入到欄位或 JavaBean 屬性的普通結果 association – 一個複雜的類型關聯;許多結果將包成這種類型 嵌入結果映射 – 結果映射自身的關聯,或者參考一個 collection – 複雜類型的集 嵌入結果映射 – 結果映射自身的集,或者參考一個 discriminator – 使用結果值來決定使用哪個結果映射 case – 基於某些值的結果映射 嵌入結果映射 – 這種情形結果也映射它本身,因此可以包含很多相 同的元素,或者它可以參照一個外部的結果映射。 關聯

<association property="author" column="blog_author_id" javaType="Author">  <id property="id" column="author_id"/>  <result property="username" column="author_username"/></association>

關聯元素處理“有一個”類型的關係。比如,在我們的樣本中,一個部落格有一個使用者。關聯映射就工作於這種結果之上。你指定了目標屬性,來擷取值的列,屬性的 java 類型(很多情況下 MyBatis 可以自己算出來),如果需要的話還有 jdbc 類型,如果你想覆蓋或擷取的結果值還需要類型控制器。

關聯中不同的是你需要告訴 MyBatis 如何載入關聯。MyBatis 在這方面會有兩種不同的方式: 巢狀查詢:通過執行另外一個 SQL 映射語句來返回預期的複雜類型。 嵌套結果:使用嵌套結果映射來處理重複的聯合結果的子集。首先,然讓我們來查看這個元素的屬性。所有的你都會看到,它和普通的只由 select 和

resultMap 屬性的結果映射不同。

<resultMap id="blogResult" type="Blog">  <association property="author" column="author_id" javaType="Author" select="selectAuthor"/></resultMap><select id="selectBlog" resultMap="blogResult">  SELECT * FROM BLOG WHERE ID = #{id}</select><select id="selectAuthor" resultType="Author">  SELECT * FROM AUTHOR WHERE ID = #{id}</select

我們有兩個查詢語句:一個來載入部落格,另外一個來載入作者,而且部落格的結果映射描述了“selectAuthor”語句應該被用來載入它的 author 屬性。

其他所有的屬性將會被自動載入,假設它們的列和屬性名稱相匹配。 集合(一對多映射)

<collection property="posts" ofType="domain.blog.Post">  <id property="id" column="post_id"/>  <result property="subject" column="post_subject"/>  <result property="body" column="post_body"/></collection>

集合元素的作用幾乎和關聯是相同的。實際上,它們也很相似,文檔的異同是多餘的。所以我們更多關注於它們的不同。

我們來繼續上面的樣本,一個部落格只有一個作者。但是部落格有很多文章。在部落格類中,這可以由下面這樣的寫法來表示:

private List<Post> posts;
要映射嵌套結果集合到 List 中,我們使用集合元素。就像關聯元素一樣,我們可以從串連中使用巢狀查詢,或者嵌套結果。
集合的巢狀查詢 首先,讓我們看看使用巢狀查詢來為部落格載入文章
<resultMap id="blogResult" type="Blog">  <collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/></resultMap><select id="selectBlog" resultMap="blogResult">  SELECT * FROM BLOG WHERE ID = #{id}</select><select id="selectPostsForBlog" resultType="Post">  SELECT * FROM POST WHERE BLOG_ID = #{id}</select>
這裡你應該注意很多東西,但大部分代碼和上面的關聯元素是非常相似的。首先,你應該注意我們使用的是集合元素。然後要注意那個新的“ofType”屬性。這個屬性用來區分JavaBean(或欄位)屬性類型和集合包含的類型來說是很重要的。所以你可以讀出下面這個映射:

<collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>

讀作: “在 Post 類型的 ArrayList 中的 posts 的集合。”

javaType 屬性是不需要的,因為 MyBatis 在很多情況下會為你算出來。所以你可以縮短寫法:

<collection property="posts" column="id" ofType="Post" select="selectPostsForBlog"/>
集合的嵌套結果
<select id="selectBlog" resultMap="blogResult">  select  B.id as blog_id,  B.title as blog_title,  B.author_id as blog_author_id,  P.id as post_id,  P.subject as post_subject,  P.body as post_body,  from Blog B  left outer join Post P on B.id = P.blog_id  where B.id = #{id}</select>
在用文章映射集合映射部落格,可以簡單寫為:

<resultMap id="blogResult" type="Blog">  <id property="id" column="blog_id" />  <result property="title" column="blog_title"/>  <collection property="posts" ofType="Post">    <id property="id" column="post_id"/>    <result property="subject" column="post_subject"/>    <result property="body" column="post_body"/>  </collection></resultMap>

同樣,要記得 id 元素的重要性,如果你不記得了,請閱讀上面的關聯部分。

同樣,如果你引用更長的形式允許你的結果映射的更多重用,你可以使用下面這個替代的映射:

<resultMap id="blogResult" type="Blog">  <id property="id" column="blog_id" />  <result property="title" column="blog_title"/>  <collection property="posts" ofType="Post" resultMap="blogPostResult" columnPrefix="post_"/></resultMap><resultMap id="blogPostResult" type="Post">  <id property="id" column="id"/>  <result property="subject" column="subject"/>  <result property="body" column="body"/></resultMap>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.