広告 Java

【MyBatis】ネストしたリスト(階層構造)をマッピングする方法

MyBatisでネストしたリストをマッピングする方法

MyBatisで親子関係になっているネストしたリスト(階層構造)をマッピングする方法を紹介します。

例えば、次のようなテーブルがあるとします。(会社テーブルと社員テーブルの関係性は1:n)

会社テーブルと社員テーブルのER図

この2つのテーブルを結合したSQL文を発行し

SELECT
    c.id
    ,c.name
    ,e.id AS employeeId
    ,e.name AS employeeName
    ,e.address
    ,e.phone
FROM
    company c INNER JOIN employee e ON c.id = e.company_id

 

次のようなオブジェクトにマッピングしたいケースはよくあります。

/**
 * 会社情報
 */
@Data
public class CompanyInfo implements Serializable {

    /**
     * 会社ID
     */
    private Long companyId;

    /**
     * 会社名
     */
    private String companyName;

    /**
     * ユーザ情報リスト
     */
    List<EmployeeInfo> employeeList;
}

 

本記事では、MyBatisを利用して上記のSQLを上記のオブジェクトにマッピングする方法を紹介します。

スポンサーリンク

SQL文(XMLファイル)

MyBatisのSQL文(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.example.demo.dao.SampleMapper">

    <resultMap id="companyMap" type="com.example.demo.dto.CompanyInfo">
        <id property="companyId" column="id"/>
        <result property="companyName" column="name" />
        <collection property="employeeList" ofType="com.example.demo.dto.EmployeeInfo">
            <id property="employeeId" column="employeeId" />
            <result property="employeeName" column="employeeName" />
            <result property="employeeAddress" column="address" />
            <result property="employeePhone" column="phone" />
        </collection>
    </resultMap>

    <select id="search" resultMap="companyMap">
        SELECT
            c.id
            ,c.name
            ,e.id AS employeeId
            ,e.name AS employeeName
            ,e.address
            ,e.phone
        FROM
            company c INNER JOIN employee e ON c.id = e.company_id
    </select>

</mapper>

resultMapで階層構造を作ります。このとき<id>の指定を忘れないように注意しましょう。

resultMapの定義では、columnにはSQLのカラム名、propertyにはjavaクラスのフィールド名 propertyを指定します。

Mapperクラス

MyBatisのMapperクラスは次のとおり。

@Mapper
public interface SampleMapper {
    List<CompanyInfo> search();
}

結果を格納するクラス

SQL文の実行結果を格納するクラスは次のとおり。

[com.example.demo.dto.CompanyInfo]

package com.example.demo.dto;

import java.io.Serializable;
import java.util.List;

import lombok.Data;

/**
 * 会社情報
 */
@Data
public class CompanyInfo implements Serializable {

    /**
     * 会社ID
     */
    private Long companyId;

    /**
     * 会社名
     */
    private String companyName;

    /**
     * ユーザ情報リスト
     */
    List<EmployeeInfo> employeeList;
}

[com.example.demo.dto.EmployeeInfo]

package com.example.demo.dto;

import lombok.Data;

/**
 * 社員情報
 */
@Data
public class EmployeeInfo {

    /**
     * 社員ID
     */
    private Long employeeId;

    /**
     * 社員名
     */
    private String employeeName;

    /**
     * 社員の住所
     */
    private String employeeAddress;

    /**
     * 社員の電話番号
     */
    private String employeePhone;
}

helpful