SSM框架學習-MyBatis篇 SQL映射文件——實現高級結果映射和多表查詢

SSM框架學習-MyBatis篇 SQL映射文件——實現高級結果映射(多表查詢)

問題情境:比如有張表,用戶和用戶詳情,這兩張表裏面沒長表都有一個id字段,這兩個表的id字段都是對應的。

實體類裏面分別對應兩個實體類,user和userdetail,還有一個很重要的實體類,叫做“用戶+用戶詳情”(userwithdetail),這個實體類首先繼承了user,裏面的元素是前面的userdetail這個對象。

比如我想要查詢一個用戶,我還想知道他的詳情,我就要在數據庫裏面select它一下,要返回userwithdetail 這個對象,因爲這這個對象既繼承了父類User,還包括了對應的對象userDetail。那麼這麼複雜的結構,肯定會使用到多表查詢。

mybatis對於處理簡單的單表查詢,用resultType就可以解決 但是對於多表查詢,都要使用resultMap進行詳細的描述 告訴mybatis怎麼封裝。

自頂向下的先實踐一下多表查詢:

1、數據庫定義user和userdetail的兩張表。這個就不多贅述。

對應的實體類,前面已經說過。其中user和userdetail都實現serializable,UserWithDetail 繼承了User

2、mybatis的配置文件先聲明一下兩個要用到的Mapper文件,這個也不多贅述

3、首先先寫一個方法,就按照id查詢一個用戶吧。這個寫法應該沒毛病。給User和UserDetail兩張表

起一個別名。然後兩表聯合查詢。

    <select id="queryById" resultMap="userWithDetailMap">
        select t1.id as uid ,t1.phone,t1.password,t1.create_date,t1.status,
        t2.id  as udid,t2.address,t2.cid
        from user t1,user_detail t2
        <where>
            t1.id=u_id
            and t1.id =#{id}
        </where>
    </select>

 4、由於從user t1,user_detail t2這兩張表裏面查詢數據,單純的語句已經不知道返回的數據的封裝規則是什麼了。resultType就不能解決問題了,那我們就定義一個resultMap

    <resultMap id="userBaseMap" type="com.sdbit.ylh.entity.UserWithDetail">
        <!--user的基本信息-->
        <id property="id" column="uid"/>
        <result property="phone" column="phone"/>
        <result property="password" column="password"/>
        <result property="createDate" column="create_date"/>
        <result property="status" column="status"/>
    </resultMap>

這裏先定義一個基本的user信息而不是userdetail,原因是這個resultmap竟然還可以繼承,爲了以後寫方便,就先給它寫一個basemap,對錶中的數據進行映射,先說說裏面的屬性

  • property:映射數據庫列(column)的實體與對象(JavaBean)的對應元素的屬性。這裏是User類的元素。
  • column:數據庫列名
  • id:id算是一個比較特殊的property,用來映射數據庫主鍵列與對象對應的元素,這裏是User的uid元素

那user的對應屬性如此,可是最後結果還有一個userdetail對象需要我們去封裝,這個應該怎麼解決呢?

那麼就需要用到上面說的resultMap的繼承。

5、這裏在寫一個resultMap,id的值爲userWithDetailMap

    <resultMap id="userWithDetailMap" extends="userBaseMap"   type="com.sdbit.ylh.entity.UserWithDetail">
        <association property="userDetail" javaType="com.sdbit.ylh.entity.UserDetail">
        <id property="id" column="udid"/>
        <result property="address" column="address"></result>
        <result property="cid" column="cid"></result>
        </association>
    </resultMap>

這裏就用到了association這個屬性,這個屬性就專門用來處理一對一的情況。這裏持有的是userDetail這一個對象,然後我們需要告訴mybatis它類型是對應實體類中的 com.sdbit.ylh.entity.UserWithDetail這個類,

這個類對應的表的屬性,和他們對應的類裏面的元素。我們在裏面繼續聲明即可,和上面一樣id和property

完事之後在看看上面指定的resultmap,就一目瞭然了。

程序成功運行,查詢出一條數據user+userdetail

 

還有一種封裝resultMap更簡單的方式,但是不是官方推薦的那種,也可以使用(這裏沒有使用繼承!):

 

實踐一下分步查詢:

分步查詢(如果查詢太複雜,可以使用分步查詢)

意思就是,當查詢很複雜的時候,我們可以先寫一個sql語句進行單表查詢,然後再在resultMap裏面再次執行一次別的sql語句

這個sql語句可以是別的mapper裏面的語句。

具體怎麼實現呢?下面就是實踐演示。

1、首先定義一個“別的”mapper,這裏叫做UserDetailMapper,顧名思義,就是專門對UserDetail的這個表進行查詢。

因爲最後我們想要得到的結果是User+UserDetail=UserWithDetail。

 

2、在sql的xml文件裏寫一個簡單的select,把UserDetail表裏面對應id的記錄查找出來。

 

3、回到UserMapper.xml,我們首先封裝一個resultMap,

    <resultMap id="userWithDetailMap3" extends="userBaseMap" type="com.sdbit.ylh.entity.UserWithDetail">
        <association property="userDetail"
                     select="com.sdbit.ylh.mapper.UserDetailMapper.queryByUserId"
                     column="uid">
        </association>
    </resultMap>

在這個語句中可以看到,association裏面的property指向的就是userwithDetail裏面的userDetail,那麼這個userDetail對象從哪裏來呢?就從select引用com.sdbit.ylh.mapper.UserDetailMapper下面的queryByUserId方法裏來,但是上面這個uid是從哪裏來呢??

那麼我們在sql語句書寫的時候,就要包含resultMap需要的列,我們現在就來寫分步查詢的最後一個sql

<select id="queryByIdByStep" resultMap="userWithDetailMap3">
        select t1.id as uid ,t1.phone,t1.password,t1.create_date,t1.status
        from user t1
        <where>
            and t1.id =#{id}
        </where>
    </select>

那麼這裏的uid就封裝好了給resultMap。resultmap就可以執行第二步查詢。完成了兩次查詢後UserWithDetail這個對象才完美的被數據填滿。

如上就完成了使用association處理一對一的關聯關係。

1對1的關聯關係總結:

  •     學會了使用association來實現多表查詢,對實體類和數據庫這兩方的映射
  •     處理多表查詢中出現bean包含bean的兩種處理方式,官方的和簡單的
  •     resultMap的繼承的寫法。
  •     使用定義resultMap來實現分步查詢,使用association,甚至可以跨mapper調用方法查詢

  

   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章