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は省略しています。


```java: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を使用する。

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



```java: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を使用する。


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


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

```java: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内のパス変数の値を取得するためのアノテーション。



```java: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要素を繰り返し出力する。


```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>
```

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