LoginSignup
6
13

More than 3 years have passed since last update.

Spring + MyBatis接続設定方法 <テーブル結合編>

Posted at

今回は2つのテーブル結合をやってみました。

1対1の場合

Entity

<親Entityクラス>

Player.java
package com.mybatis.test.domain;

import java.util.List;

import lombok.Data;

@Data
public class Player {

    private String id;
    private String name;
    private String age;
    //子クラスの要素を定義(1対1)
    private Detail detailIds;
}

<子Entityクラス>

Detail.java
package com.mybatis.test.domain;

import lombok.Data;

@Data
public class Detail {

    private String detailId;
    private String work;
}

テーブルの親子関係はdetail_idで結びつくので、Player.javaに子要素の変数を用意する。

XML

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.mybatis.test.domain.MyBatisMapper">
    <select id="selectItem" resultMap="playerMap">
     SELECT
      player.id
      ,player.name
      ,player.detail_id
      ,detail.work
     FROM
      player
     JOIN
      detail
     ON
      player.detail_id=detail.detail_id
     WHERE
      player.id=#{id}
    </select>

    <!-- テーブルのSELECT結果をどのようにマッピングするか指定 -->
    <resultMap id="playerMap" type="com.mybatis.test.domain.Player">
      <id property="id" column="id" />
      <result property="name" column="name" />
      <association property="detailIds" resultMap="detailResult"/>
    </resultMap>

      <resultMap id="detailResult" type="com.mybatis.test.domain.Detail">
        <result property="detailId" column="detail_id" />
        <result property="work" column="work" />
      </resultMap>

</mapper>
テーブル結合する条件(detail_id)は必ずSQLに盛り込むこと。

検索の結果は resultMap要素で別途定義する。

resultMapでは、実際に検索結果で得たい内容(今回はPlayer)に対する結果のマッピングを行う。
property は Javaクラス側のプロパティ(変数)を指す。
columnはSQLのカラムを指す。

また、今回は1:1の関係なので、associationを使用する。
associationのresultMapで子要素と対応付けする。

Interface

MyBatisMapper.java
package com.mybatis.test.domain;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface MyBatisMapper {

    //JOINのテスト用
    public Player selectItem(String id);

Service

MyBatisService.java
package com.mybatis.test.domain;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyBatisService {

    @Autowired
    MyBatisMapper mapper;
    //JOIN
    @Transactional
    public Player selectItem(String id) {
        return mapper.selectItem(id);
    }

Controller

Controller
@Controller
public class MybatisController {
    @Autowired
    MyBatisService myBatisService;
        Player player = new Player();
        player = myBatisService.selectItem("002");
        model.addAttribute("playerDetail", player);
        return "index";
}

Jsp

    <div th:object="${playerDetail}">
        <div>
            <label><b>名前</b></label>
            <p th:text="${playerDetail.name}">
        </div>
        <div>
            <label><b>仕事</b></label>
            <p th:text="${playerDetail.detailIds.work}">
        </div>
    </div>

1対多の場合

Entity

<親Entity>

Player.java
package com.mybatis.test.domain;

import java.util.List;

import lombok.Data;

@Data
public class Player {

    private String id;
    private String name;
    private String age;
    private Detail detailIds;
    //子クラスの要素定義(1対多)
    private List<Item> items;
}

1対多なので、フィールドにList型を定義した。

<子Entity>

Item.java
package com.mybatis.test.domain;

import lombok.Data;

@Data
public class Item {

    private String id;
    private String item;
}

XML

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.mybatis.test.domain.MyBatisMapper">
      <select id="selectChoice" resultMap="itemMap">
      select
       player.id
       ,player.name
       ,item.items
      from
       player
      join
       item
      on
       player.id = item.id
      where
       player.id=#{id}
      </select>

      <!-- テーブルのSELECT結果をどのようにマッピングするか指定 -->
      <resultMap id="itemMap" type="com.mybatis.test.domain.Player">
       <id property="id" column="id" />
       <result property="name" column="name" />
       <collection property="items" ofType="com.mybatis.test.domain.Item">
        <result property="id" column="id" />
        <result property="item" column="items" />
       </collection>
      </resultMap>
</mapper>

1対多の場合は、collectionタグを使用する。(1対1の場合はassociationタグ)
collectionタグのpropertyには、子クラス(Item.java)を束ねる親クラス(Player.java)のフィールド(items)を設定する。
ofTypeで、子クラスを指定する。

ここでも、

テーブル結合する条件(detail_id)は必ずSQLに盛り込むこと。

interfaceやserviceなどは割愛。

Controller

MybatisController.java
@Controller
public class MybatisController {
    @Autowired
    MyBatisService myBatisService;
    @GetMapping()
    public String index(Model model) {
        Player playerChoise = myBatisService.selectChoice("002");
        //Item型のリストに詰めなおす
        List<Item> itemsList = playerChoise.getItems();
        model.addAttribute("itemsList", itemsList);

Jsp

    <!-- th:eachで要素を1つずつ取得する -->
    <div th:each="item : ${itemsList}">
    <p th:text="${item.item}">
    </div>
6
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
13