Xmlベースで結合SQLによるマッピング実装
前回はSQLを3つ使用してネストされたオブジェクトへのマッピングを実装していましたが、Xmlの場合であればFrom句を複数指定した結合SQLでのマッピングも可能です。
※アノテーションベースではできません。
コード
DemoMapperXml.java
package com.example.demo.repository;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.example.demo.entity.Country;
@Mapper
public interface DemoMapperXml {
Country selectCountry(@Param("id") Integer id);
}
アノテーションベースに比べるとすっきりしています。
DemoMapperXml.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.repository.DemoMapperXml">
<resultMap id="countryMap" type="com.example.demo.entity.Country" >
<!-- <result column="country_id" property="countryId" /> -->
<result column="country" property="country" />
<result column="last_update" property="lastUpdate" />
<association property="id" >
<result column="country_id" property="countryId" />
</association>
<collection property="city" ofType="com.example.demo.entity.City">
<result column="city_id" property="cityId" />
<result column="city" property="city" />
<result column="last_update" property="lastUpdate" />
<collection property="address" ofType="com.example.demo.entity.Address">
<result column="address_id" property="addressId" />
<result column="address" property="address" />
<result column="address2" property="address2" />
<result column="district" property="district" />
<result column="postal_code" property="postalCode" />
<result column="phone" property="phone" />
<result column="last_update" property="lastUpdate" />
</collection>
</collection>
</resultMap>
<select
id="selectCountry"
resultMap="countryMap">
SELECT *
FROM
country,
city,
address
WHERE
country.country_id = #{id}
AND
country.country_id = city.country_id
AND
city.city_id = address.city_id
</select>
</mapper>
説明
まず、SQL文が変わっています。
前回までのSQLではそれぞれのテーブルに対して主キーなどから対応するレコードを取得していましたが、
今回はそれぞれのSQLの条件を一気に指定しています。
後は結果を格納するだけです。
collectionでネストしているオブジェクトを指定し、さらにネストしている場合はcollectionを追加で指定しているという入れ子の構造になっています。
結果
他のマッピング実装と同じくオブジェクトがマッピングできています。
まとめ
ここまでで3つの実装方法を説明してきましたが、前回までの二つの実装
- DemoMapperがアノテーションベースのマッピング実装
- DemoMapperXmlがXmlベースで結合SQLによるマッピング実装
については注意が必要です。
なぜならネストした階層ごとにSQLを発行する必要があるため、
ManyからManyのネストなどに対しては大量にSQLを発行してしまい性能面で影響が出る可能性があるためです。
N+1問題とも言われています。
なので、可能であれば複合キーを使って必要なカラムを取得し、Xmlベースでマッピングをしたほうがいいかもしれません。
This article assumes you are comfortable with Spring Boot and REST APIs. It will help you integrate MyBatis in your Spring-Boot project and develop some example interactions with a MySQL database. At the end of this tutorial you will have all you need to create basic interactions with a relational database (including transactions and pool size limits) and unit-test those interactions with an in-memory database.