Mybatis中多表關聯時,怎么利用association優雅寫resultMap來映射vo


前言

有好一陣沒碰mybatis了,這次的項目基於性能考慮,選了mybatis,寫着寫着,發現有下面的需求,比如兩表聯查,取其中各一部分字段,怎么更方便地用vo來接,這里犯了難;

我想的是,因為這個sql聯查的vo,能不能直接使用兩個表的po來接呢,比如下面這種:

Users、SeatInformation都是對應了數據庫兩張表的po
@Data
public class UserSeatUnionQueryVO {
    private Users users;

    private SeatInformation seatInformation;
}

折騰了2個小時,網上各種找不到類似需求,終於搞出來了,還是值得記錄和分享。

一、兩表關聯,映射到如下類型vo(拷貝單表po屬性,組合另一單表的po),怎么寫

sql:


    <select id="selectOnlineUserBySeatState" resultMap="UserSeatUnionQueryVOResultMap">
        SELECT
            u.`user_id`,u.`account_status`,s.*
        FROM
            users u,
            seat_information s
        WHERE u.`user_id` = s.`user_id`
              AND u.`account_status` = 1
              AND u.`delete_status` = 1
              AND u.`center_id` = 0
              AND s.`token` IS NOT NULL
              AND s.`seat_state` = 1
              AND s.delete_status = 1
    </select>

假設我想映射的vo如下:

@Data
public class UserSeatUnionQueryVO {

    /**
     * 用戶Id
     */
    @ApiModelProperty(value = "用戶Id")
    @TableId(value = "user_id", type = IdType.ID_WORKER)
    private Long userId;


    /**
     * 賬號狀態,-1停用,1啟用
     */
    @ApiModelProperty(value = "賬號狀態,-1停用,1啟用")
    private Integer accountStatus;

	/**
	 * 這里的SeatInformation是表seat_information對應的po
	 */
    private SeatInformation seatInformation;
}

則mapper中應該這樣寫:

UsersMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ceiec.cad.mapper.UsersMapper">

    <!-- 通用查詢映射結果 -->
    <resultMap id="BaseResultMap" type="com.ceiec.cad.model.Users">
        <id column="user_id" property="userId" />
        <result column="account_status" property="accountStatus" />
    </resultMap>


    <resultMap id="UserSeatUnionQueryVOResultMap" type="com.ceiec.cad.service.UserSeatUnionQueryVO">
        <id column="user_id" property="userId" />
        <result column="account_status" property="accountStatus" />
        <association property="seatInformation"  javaType="com.ceiec.cad.model.SeatInformation" resultMap="com.ceiec.cad.mapper.SeatInformationMapper.BaseResultMap">

        </association>

    </resultMap>


    <select id="selectOnlineUserBySeatState" resultMap="UserSeatUnionQueryVOResultMap">
        SELECT
            u.`user_id`,u.`account_status`,s.*
        FROM
            users u,
            seat_information s
        WHERE u.`user_id` = s.`user_id`
              AND u.`account_status` = 1
              AND u.`delete_status` = 1
              AND u.`center_id` = 0
              AND s.`token` IS NOT NULL
              AND s.`seat_state` = 1
              AND s.delete_status = 1
    </select>
</mapper>

SeatInformationMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ceiec.cad.mapper.SeatInformationMapper">

    <!-- 通用查詢映射結果 -->
    <resultMap id="BaseResultMap" type="com.ceiec.cad.model.SeatInformation">
        <id column="seat_information_id" property="seatInformationId" />
      	//省略無關代碼
    </resultMap>

</mapper>

二、兩表關聯,映射到如下類型vo(組合兩表po),怎么寫

上面的方案呢,假設A關聯B,在vo里,相當於是把B組合進了A;我想的是,能不能新建一個vo,同時組合A和B呢,比如下面這樣:

@Data
public class UserSeatUnionQueryVO {
    private Users users;

    private SeatInformation seatInformation;
}

sql:

和方案一一樣。

UsersMapper.xml:


    <resultMap id="UserSeatUnionQueryVOResultMap" type="com.ceiec.cad.service.UserSeatUnionQueryVO">
        <association property="users"  javaType="com.ceiec.cad.model.Users" resultMap="com.ceiec.cad.mapper.UsersMapper.BaseResultMap">

        </association>
        <association property="seatInformation"  javaType="com.ceiec.cad.model.SeatInformation" resultMap="com.ceiec.cad.mapper.SeatInformationMapper.BaseResultMap">

        </association>

    </resultMap>

注意這里的 association元素中的resultMap字段,引用了其他Mapper文件的BaseResultMap

格式是:其他Mapper文件的namespace,加上resultMap的名字。

這里附上SeatInformationMapper.xml的內容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ceiec.cad.mapper.SeatInformationMapper">

    <!-- 通用查詢映射結果 -->
    <resultMap id="BaseResultMap" type="com.ceiec.cad.model.SeatInformation">
        <id column="seat_information_id" property="seatInformationId" />
      	//省略無關
    </resultMap>

</mapper>

下面附上完整的usersMapper.xml的內容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ceiec.cad.mapper.UsersMapper">

    <!-- 通用查詢映射結果 -->
    <resultMap id="BaseResultMap" type="com.ceiec.cad.model.Users">
        <id column="user_id" property="userId" />
        <result column="account_status" property="accountStatus" />
    </resultMap>


    <resultMap id="UserSeatUnionQueryVOResultMap" type="com.ceiec.cad.service.UserSeatUnionQueryVO">
        <association property="users"  javaType="com.ceiec.cad.model.Users" resultMap="com.ceiec.cad.mapper.UsersMapper.BaseResultMap">

        </association>
        <association property="seatInformation"  javaType="com.ceiec.cad.model.SeatInformation" resultMap="com.ceiec.cad.mapper.SeatInformationMapper.BaseResultMap">

        </association>

    </resultMap>


    <select id="selectOnlineUserBySeatState" resultMap="UserSeatUnionQueryVOResultMap">
        SELECT
            u.*,s.*
        FROM
            users u,
            seat_information s
        WHERE u.`user_id` = s.`user_id`
              AND u.`account_status` = 1
              AND u.`delete_status` = 1
              AND u.`center_id` = 0
              AND s.`token` IS NOT NULL
              AND s.`seat_state` = 1
              AND s.delete_status = 1
    </select>
</mapper>

展示下效果:

可以看到,最后這種,這么寫沒問題。

三、官網文檔

我在官網看了半天,后來才找到類似的例子:

https://mybatis.org/mybatis-3/sqlmap-xml.html

因為文檔很長,上面這個圖,大家可以通過打開上面的網址后,搜索 Multiple ResultSets for Association到達該位置。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM