LoginSignup
23
33

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-05-12

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>

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

23
33
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
23
33