1. 程式人生 > >Mybatis的一對多(collection)和一對一(association)查詢

Mybatis的一對多(collection)和一對一(association)查詢

del 建表 def mapping p s 新的 ron 語句塊 user

1、mybatis支持映射復雜的查詢結果集

2、表之間的關系

技術分享

3、實體及其對應關系:

技術分享

@Data
@EqualsAndHashCode(callSuper = false)
public class TestOne implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;    //
    private String nickname;    //
    private List<TestTwo> testTwos;
}
@Data
@EqualsAndHashCode(callSuper 
= false) public class TestTwo implements Serializable { private static final long serialVersionUID = 1L; private Integer id; // private String nickname; // private Integer oneId; // private TestOne testOne; }

4、mybatis---------Association: 一對一查詢的方式

<resultMap id="TestTwoAll"
type="TestTwo"> <id property="id" column="twoid"/> <result property="nickname" column="twonickname"/> <result property="oneId" column="one_id"/> <association property="testOne" column="one_id" javaType="TestOne"> <id property="id"
column="oneid"/> <result property="nickname" column="onenickname"/> </association> </resultMap> <select id="getTotalById" resultMap="TestTwoAll" parameterType="long"> SELECT one.id as oneid, one.nickname as onenickname, two.id as twoid, two.nickname as twonickname, two.one_id FROM test_one one,test_two two where one.id=two.one_id and two.id=#{value} </select>

5、mybatis---------Collection: 一對多查詢的方式

<resultMap id="TestOneAll" type="TestOne">
        <result property="id" column="oneid"/>
        <result property="nickname" column="onenickname"/>
        <collection property="testTwos" column="one_id" ofType="TestTwo" javaType="ArrayList">
            <result property="id" column="twoid"/>
            <result property="nickname" column="twonickname"/>
            <result property="oneId" column="one_id"/>
        </collection>
    </resultMap>

    <select id="getTotalById" resultMap="TestOneAll" parameterType="long">
        SELECT
        one.id as oneid,
        one.nickname as onenickname,
        two.id as twoid,
        two.nickname as twonickname,
        two.one_id
        FROM test_one one,test_two two
        where one.id=two.one_id and one.id=#{VALUE }
        order by twoid desc
    </select>

附錄:

(1)建表語句:

CREATE TABLE `test_one` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;



CREATE TABLE `test_two` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) NOT NULL,
  `one_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `test_two_ibfk_1` (`one_id`),
  CONSTRAINT `test_two_ibfk_1` FOREIGN KEY (`one_id`) REFERENCES `test_one` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

(2)說明:(引自 http://blog.csdn.net/wxwzy738/article/details/24742495)

  1》

id, result元素

<id property="id" column="post_id"/>

<result property="subject" column="post_subject"/>

這是最基本的結果集映射。idresult 將列映射到屬性或簡單的數據類型字段(String, int, double, Date等)。

這兩者唯一不同的是,在比較對象實例時id 作為結果集的標識屬性。這有助於提高總體性能,特別是應用緩存和嵌套結果映射的時候。

  2》

Association元素

<association property="author" column="blog_author_id" javaType=" Author">

<id property="id" column="author_id"/>

<result property="username" column="author_username"/>

</association>

Association元素處理“has-one”(一對一)這種類型關系。聯合映射與其它的結果集映射工作方式差不多,指定property、column、javaType(通常MyBatis會自動識別)、jdbcType(如果需要)、typeHandler。

不同的地方是您需要告訴MyBatis 如何加載一個聯合查詢。MyBatis使用兩種方式來加載:

·Nested Select:通過執行另一個返回預期復雜類型的映射SQL語句(即引用外部定義好的SQL語句塊)。

·Nested Results:通過嵌套結果映射(nested result mappings)來處理聯接結果集(joined results)的重復子集。

首先,讓我們檢查一下元素屬性。正如您看到的,它不同於普通只有select和resultMap屬性的結果映射。

Attribute

Description

property

映射數據庫列的字段或屬性。如果JavaBean 的屬性與給定的名稱匹配,就會使用匹配的名字。否則,MyBatis 將搜索給定名稱的字段。兩種情況下您都可以使用逗點的屬性形式。比如,您可以映射到”username”,也可以映射到更復雜點的”address.street.number”。

column

數據庫的列名或者列標簽別名。與傳遞給resultSet.getString(columnName)的參數名稱相同。

註意: 在處理組合鍵時,您可以使用column= “{prop1=col1,prop2=col2}”這樣的語法,設置多個列名傳入到嵌套查詢語句。這就會把prop1和prop2設置到目標嵌套選擇語句的參數對象中。

javaType

完整java類名或別名(參考上面的內置別名列表)。如果映射到一個JavaBean,那MyBatis 通常會自行檢測到。然而,如果映射到一個HashMap,那您應該明確指定javaType 來確保所需行為。

jdbcType

支持的JDBC類型列表中列出的JDBC類型。這個屬性只在insert,update 或delete 的時候針對允許空的列有用。JDBC 需要這項,但MyBatis 不需要。如果您直接編寫JDBC代碼,在允許為空值的情況下需要指定這個類型。

typeHandler

我們已經在文檔中討論過默認類型處理器。使用這個屬性可以重寫默認類型處理器。它的值可以是一個TypeHandler實現的完整類名,也可以是一個類型別名。

聯合嵌套選擇(Nested Select for Association)

select

通過這個屬性,通過ID引用另一個加載復雜類型的映射語句。從指定列屬性中返回的值,將作為參數設置給目標select 語句。表格下方將有一個例子。註意:在處理組合鍵時,您可以使用column=”{prop1=col1,prop2=col2}”這樣的語法,設置多個列名傳入到嵌套語句。這就會把prop1和prop2設置到目標嵌套語句的參數對象中。

  3》

Collection元素

<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>

collection元素的作用差不多和association元素的作用一樣。事實上,它們非常相似,以至於再對相似點進行描述會顯得冗余,因此我們只關註它們的不同點。

會像下面這樣定義相應屬性:

private List<Post> posts;

映射一個嵌套結果集到一個列表,我們使用collection元素。就像association 元素那樣,我們使用嵌套查詢,或者從連接中嵌套結果集。

<resultMap id=”blogResult” type=”Blog”>
<collection property="posts" javaType=”ArrayList” column="blog_id"
ofType="Post" select=”selectPostsForBlog”/>
</resultMap>

<select id=”selectBlog” parameterType=”int” resultMap=”blogResult”>
SELECT * FROM BLOG WHERE ID = #{id}
</select>

<select id=”selectPostsForBlog” parameterType=”int” resultType="Author">
SELECT * FROM POST WHERE BLOG_ID = #{id}
</select>

* 一看上去這有許多東西需要註意,但大部分看起與我們在association元素中學過的相似。首先,您會註意到我們使用了collection元素,然後會註意到一個新的屬性“ofType”。這個元素是用來區別JavaBean屬性(或者字段)類型和集合所包括的類型。因此您會讀到下面這段代碼。

<collection property="posts" javaType=”ArrayList” column="blog_id"

ofType="Post" select=”selectPostsForBlog”/>

理解為:“一個名為posts,類型為Post的ArrayList集合(A collection of posts in an ArrayList of type Post)” 。

javaType屬性不是必須的,通常MyBatis 會自動識別,所以您通常可以簡略地寫成:

<collection property="posts" column="blog_id" ofType="Post"

select=”selectPostsForBlog”/>

Mybatis的一對多(collection)和一對一(association)查詢