Help us understand the problem. What is going on with this article?

Spring Boot + Spring Data JPA複数のテーブル結合について

Springを使用してのINNER JOINやLEFT JOINなど参考書を読んでも苦戦したので、備忘録として記載します。

今回実現したいこと

部屋名と備品名を画面に出力する。

Roomテーブル

       カラム名      データ型
部屋番号 room_id      INT
部屋名 room_name     VARCHAR

Equipmentテーブル

       カラム名     データ型
備品番号 equipmentId_id   INT
備品名 equipment_name   VARCHAR
部屋番号 room_id     INT

Entity(RoomとEquipment)を作成します。
importは省略しています。

Room.java
@Entity
public class Room implements Serializable {

    @Id
    @GeneratedValue
    private Integer roomId;

    private String roomName;

    @OneToMany(mappedBy="room", cascade=CascadeType.ALL)
    private List<Equipment> equipments;

    public Integer getRoomId() {
        return roomId;
    }

    public void setRoomId(Integer roomId) {
        this.roomId = roomId;
    }

    public String getRoomName() {
        return roomName;
    }

    public void setRoomName(String roomName) {
        this.roomName = roomName;
    }

    public List<Equipment> getEquipments() {
        return equipments;
    }

    public void setEquipments(List<Equipment> equipments) {
        this.equipments = equipments;
    }
}

Equipmentに対して1対多の関係なので、@OneToManyを使用する。

@OneToMany(mappedBy="room", cascade=CascadeType.ALL)
private List<Equipment> equipments;
Equipment.java
@Entity public class Equipment implements Serializable {

    @Id
    @GeneratedValue
    private Integer equipmentId;

    private String equipmentName;


    @ManyToOne
    @JoinColumn(name="room_id")
    private Room room;

    public Integer getEquipmentId() {
        return equipmentId;
    }

    public void setEquipmentId(Integer equipmentId) {
        this.equipmentId = equipmentId;
    }

    public String getEquipmentName() {
        return equipmentName;
    }

    public void setEquipmentName(String equipmentName) {
        this.equipmentName = equipmentName;
    }

    public Room getRoom() {
        return room;
    }

    public void setRoom(Room room) {
        this.room = room;
    }
}

Roomに対して多対1の関係なので、@ManyToOneを使用する。
外部キーとして、@JoinColumnでroom_idを使用する。

@ManyToOne
@JoinColumn(name="room_id")
private Room room;

Repositoryで@Queryを使用してクエリを作成する。
@Param("roomId")で動的に値を設定することができる。

EquipmentRepository.java
public interface EquipmentRepository extends JpaRepository<Equipment, Integer> {

    @Query("SELECT DISTINCT e FROM Equipment e INNER JOIN e.room WHERE e.room.roomId = :roomId ORDER BY e.equipmentId")
    List<Equipment> find(@Param("roomId") Integer roomId);
}

@AutowiredでEquipmentRepositoryをインジェクションする。
@PathVariable("id")でURL内のパス変数の値を取得するためのアノテーション。

TestController.java
@Controller
public class TestController {


    @Autowired
    EquipmentRepository equipmentRepository;

    @GetMapping("/{id}")
    public String index(@PathVariable("id")Integer id, Model model) {

        List<Equipment> list2 =equipmentRepository.find(id);
        model.addAttribute("lists2", list2);


        return "index";
    }
}

th:eachで指定された配列値の数だけHTML要素を繰り返し出力する。

index.html
<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <table>
        <tr>
            <th>部屋</th>
            <th>備品</th>
        </tr>
        <tr th:each="list2:${lists2}">
            <td th:text="${list2.room.roomName}">
            <td th:text="${list2.equipmentName}">

        </tr>
    </table>
</body>
</html>

以上で、部屋名と備品名を出力することが出来ました。
今後はもっとテーブル数を増やして複雑な処理にも挑戦したいです。

wataru908
学んだことなどを備忘録としてまとめていきます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away