標籤:
Mapper.xml對應檔轉載:http://loveshisong.cn/mybatis/2015/01/22/MyBatis(%E4%B8%89)Mapper.xml%E6%98%A0%E5%B0%84%E6%96%87%E4%BB%B6.html本文結構
- select 語句簡介
- insert update delete 簡介
- Parameters 參數
- ResultMap
select 語句簡介
查詢語句是 MyBatis 中最常用的元素之一,先來個例子
<select id="selectPerson" parameterType="int" resultType="hashmap"> SELECT * FROM PERSON WHERE ID = #{id}</select>
其中的XXXType使用的都是完全限定名或者別名,其中的符號#{id}會使用預先處理語句,在 SQL 中會由一個“?”來標識,在JDBC中相當於這樣:
// Similar JDBC code, NOT MyBatis…String selectPerson = "SELECT * FROM PERSON WHERE ID=?";PreparedStatement ps = conn.prepareStatement(selectPerson);ps.setInt(1,id);
select 元素還有很多屬性
id | 在命名空間中唯一的標識符, 可以被用來引用這條語句resultType | 如果是集合情形, 那應該是集合可以包含的類型, 而不能是集合本身. 比如返回的結果是多個Persion, 這裡應該寫Persion而不是ListresultMap | 外部resultMap的命名引用, 與resultType不能同時使用. 後面會具體講parameterType | 預設值:unset. 可選, MyBatis可以通過TypeHandler推斷出具體傳入語句的參數flushCache | 預設值:false. true表示任何時候只要語句被調用, 都會導致本機快取和二級緩衝都會被清空useCache | 預設值:true. true表示本條語句的結果被二級緩衝timeout | 預設:unset. 在拋出異常之前, 驅動程式等待資料庫返回請求結果的秒數resultSetType | 預設:unset. 取值為FORWARD_ONLY,SCROLL_SENSITIVE或SCROLL_INSENSITIVE中的一個fetchSize | 預設:unset. 驅動程式每次批量返回的結果行數和這個設定值相等statementType | 預設值:PREPARED. STATEMENT,PREPARED或CALLABLE的一個. 這會讓MyBatis分別使用Statement,PreparedStatement或CallableStatementdatabaseId | 如果配置了 databaseIdProvider, MyBatis 會載入所有的不帶databaseId或匹配當前databaseId的語句;如果帶或者不帶的語句都有,則不帶的會被忽略resultOrdered | 預設值:false. 這個設定僅針對嵌套結果select語句適用:如果為 true,就是假設包含了嵌套結果集或是分組了,這樣的話當返回一個主結果行的時候,就不會發生有對前面結果集的引用的情況. 這就使得在擷取嵌套的結果集的時候不至於導致記憶體不夠用resultSets | 這個設定僅對多結果集的情況適用, 它將列出語句執行後返回的結果集並每個結果集給一個名稱,名稱是逗號分隔的
insert, update 和 delete 簡介
insert, update, delete同select類似,也有許多屬性,其中
id, parameterType, timeout, statementType, databaseId與select元素中的屬性相同;
flushCache的預設值為‘true‘
- 還有些是
insert和update所特有的屬性,如:
useGeneratedKeys | 預設值:false. 為true時會令MyBatis使用JDBC的getGeneratedKeys方法來取出由資料庫內部產生的主鍵keyProperty | 預設:unset. 唯一標記一個屬性,MyBatis會通過getGeneratedKeys的傳回值或者通過insert語句的selectKey子項目設定它的索引值. 如果希望得到多個產生的列,也可以是逗號分隔的屬性名稱列表keyColumn | 通過產生的索引值設定表中的列名,當主鍵列不是表中的第一列的時候需要設定. 如果希望得到多個產生的列,也可以是逗號分隔的屬性名稱列表
例如下面這段代碼,如果你的資料庫支援自動產生主鍵的欄位(比如 MySQL 和 SQL Server),那麼你可以設定 useGeneratedKeys=”true”,然後再把 keyProperty 設定到目標屬性上就OK了。
<insert id="insertAuthor" useGeneratedKeys="true" keyProperty="id"> insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})</insert>
Parameters 參數
參數是 MyBatis 非常強大的功能, parameterType="anyType"其中的anyType可以是int等基本類型,也可以是User等複雜類型。
<insert id="insertUser" parameterType="User"> insert into users (id, username, password) values (#{id}, #{username}, #{password})</insert>
上例中,傳入的事複雜類型User,將會在User中尋找id、username 和 password 屬性,並放入對應位置。如果是int或String等類型,不存在屬性,則直接將其值放入對應的位置。
另外,參數映射也可以指定映射類型,甚至可以指定類型處理器,像之前講一樣,javaType通常可以根據參數對象去推測。
#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
字串替換
預設情況下,使用#{}格式的文法會建立預先處理語句屬性並安全地設定值(比如?)。不過有時只想直接在 SQL 陳述式中插入一個不改變的字串,就可以這樣使用參數:
ORDER BY ${columnName}
這裡 MyBatis 不會修改或逸出字元串
ResultMap
resultMap 元素是MyBatis中最重要最強大的元素,resultMap元素本身有一些屬性,如下代碼,id用於標識該resultMap,type用於指定該resultMap映射到哪個JavaBean
<resultMap id="blogResultMap" type="Blog">...</resultMap>
它還有很多子項目,下面是resultMap元素的概念圖
resultMap
- constructor - 類在執行個體化時,用來注入結果到構造方法中
- idArg - ID 參數;標記結果作為 ID 可以協助提高整體效能
- arg - 注入到構造方法的一個普通結果
- id – 一個 ID 結果;標記結果作為 ID 可以協助提高整體效能
- result – 注入到欄位或 JavaBean 屬性的普通結果
- association – 一個複雜的類型關聯;許多結果將包成這種類型
- 嵌入結果映射 – 結果映射自身的關聯,或者參考一個
- collection – 複雜類型的集
- discriminator – 使用結果值來決定使用哪個結果映射
- case – 基於某某些值的結果映射
- 嵌入結果映射 – 這種情形結果也映射它本身,因此可以包含很多相 同的元素,或者它可以參照一個外部的結果映射
注意由於DTD的限制,這些元素出現的順序必須按照上面的順序
下面詳細說明resultMap的每個子項目
id和result
這是最基本的內容,這兩者之間的唯一不同是id所指定屬性將是能夠唯一標識對象的屬性,這能提高效率,特別是有聯合映射時。
id和reslut元素有column, property, javaType, jdbcType, typeHandler等屬性,其中column用於指定資料庫中的列名,property用於指定JavaBean對應的屬性,其他屬性則與之前講的一樣。
<id column="id" property="id"/><result column="user_name" property="username"/>
構造方法constructor
如果resultMap所映射的JavaBean的構造方法需要提供參數,則constructor就不能缺少了
constructor有idArg和arg兩個子項目,意義差不多(參見id和result的區別),都是給構造方法提供參數。他們的屬性也同id和result一樣
constructor常用的形式如下:
<constructor> <idArg column="id" javaType="int"/> <arg column="username" javaType="String"/></constructor>
注意 Java 沒有自查(反射)參數名的方法,所以要保證這裡的參數順序同JavaBean定義的順序一致,而且資料類型也是確定的。
關聯association
關聯元素處理“有一個”類型的關係。比如,一個部落格有一個作者,就像下面這樣
//來自 Author.javapublic class Author { private Integer id; private String name; private Integer age; ...}//來自 Blog.javapublic class Blog { private Integer id; private String title; private String content; private Author author; //資料庫中對應的欄位是 author_id int類型 ...}
可以這樣做級聯查詢
<resultMap id="BlogResultMap" type="Blog"> <id column="id" property="id"/> <result column="title" property="title"/> <result column="content" property="content"/> <!-- 只要提供了傳回型別,像上面的id和result指定的欄位,即使不指定MyBatis也能自動封裝 --> <association column="author_id" property="author" javaType="Author" select="com.test.mybatis.mapper.AuthorMapper.selectAuthorById"/> <!-- 這裡如果起了別名也可使用 --></resultMap><select id="selectBlogById" parameterType="int" resultMap="BlogResultMap"> SELECT * FROM blog WHERE id = #{id}</select><!-- 來自 AuthorMapper.xml --><select id="selectAuthorById" parameterType="int" resultType="Author"> SELECT * FROM author WHERE id = #{id}</select>
association是通過把column指定的欄位作為參數,傳給select子查詢的。
集合collection
如果部落格有了許多評論,則會出現“一對多”的情形,比如上面的Blog會多出一個屬性
//Blog.java新增的屬性 private List<Comment> comments;//Comment.javapublic class Comment { private Integer id; private String content; private Blog blog; ...}
那麼對於Blog的查詢將變成這樣
<resultMap id="BlogResultMap" type="Blog"> <id column="id" property="id"/> <result column="title" property="title"/> <result column="content" property="content"/> <!-- 只要提供了傳回型別,像上面的id和result指定的欄位,即使不指定MyBatis也能自動封裝 --> <association column="author_id" property="author" javaType="Author" select="com.test.mybatis.mapper.AuthorMapper.selectAuthorById"/> <!-- 這裡如果起了別名也可使用 --> <collection property="comments" javaType="ArrayList" column="id" ofType="Comment" select="com.test.mybatis.mapper.CommentMapper.selectCommentForBlog"/></resultMap><select id="selectBlogById" parameterType="int" resultMap="BlogResultMap"> SELECT * FROM blog WHERE id = #{id}</select><!-- 來自 AuthorMapper.xml --><select id="selectAuthorById" parameterType="int" resultType="Author"> SELECT * FROM author WHERE id = #{id}</select><!-- 來自 CommentMapper.xml --><select id="selectCommentForBlog" parameterType="int" resultType="Comment"> SELECT * FROM comment WHERE blog_id = #{id}</select>
其中的ofType用於表示集合中所存放的類型,上面可以理解為產生了一個ArrayList<Comment> comments,javaType屬性可以省略;column指定了id作為傳入參數
MyBatis——Mapper.xml對應檔