[Spring Boot][java] app開発3

SpringBootのリポジトリとは?
-> DBへのアクセスを自動で作成する便利インターフェース
-> DBへのCRUDを自動で実装してくれる
なるほど

Listとは?
-> Javaのリスト(List)とは、重複した要素を含むことができる順序の付けられたコレクション
-> 配列とは異なる

ReservationRepository.java

package mrs.domain.repository.reservation;

import java.util.List;

import mrs.domain.model.ReservableRoomId;
import mrs.domain.model.Reservation;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ReservationRepository extends JpaRepository<Reservation, Integer>{
	List<Reservation> findByReservableRoom_ReservableRoomIdOrderByStartTimeAsc(
			ReservableRoomId reservableRoomId);
}

MeetingRoomRepository.java

package mrs.domain.repository.room;

import org.springframework.data.jpa.repository.JpaRepository;

import mrs.domain.model.MeetingRoom;

public interface MeetingRoomRepository extends JpaRepository<MeetingRoom, Integer>{
	
}

Serviceとは?
-> ビジネスロジックを実装するクラス
-> Controllerはリクエストの窓口になるクラス
ん、ビジネスロジックはcontrollerではなく、serviceで書くのか。ちょっと混乱するな。

ReservationService.java

package mrs.domain.service.reservation;

import java.util.List;

import mrs.domain.model.*;
import mrs.domain.repository.reservation.ReservationRepository;

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

@Service
@Transactional
public class ReservationService {
	@Autowired
	ReservationRepository reservationRepository;
	
	public List<Reservation> findReservations(ReservableRoomId reservableRoomId){
		return reservationRepository.findByReservableRoom_ReservableRoomIdOrderByStartTimeAsc(
				reservableRoomId);
	}
}

Serviceの中のpublic List<*>がJavaの構文でないような印象だが、どういう事なんだ?

package mrs.domain.service.reservation;

import java.util.List;

import mrs.domain.model.*;
import mrs.domain.repository.reservation.ReservationRepository;

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

@Service
@Transactional
public class ReservationService {
	@Autowired
	ReservationRepository reservationRepository;
	@Autowired
	ReservableRoomRepository reservableRoomRepository;
	
	public Reservation reserve(Reservation reservation) {
		ReservableroomId reservableRoomId = reservation.getReservableRoom().getReservableRoomId();
		ReservableRoom reservable = reservableRoomRepository.findOne(reservableRoomId);
		if(reservable == null) {
			
		}
		boolean overlap = reservationRepository.findByReservableRoom_ReservableRoomIdOrderByStartTimeAsc(reservableRoomId)
				.stream()
				.anyMatch(x -> x.overlap(reservation));
		if(overlap) {
			
		}
		reservationRepository.save(reservation);
		return reservation;
	}

ReservationsController.java

package mrs.app.reservation;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import mrs.domain.model.*;
import mrs.domain.service.reservation.*;
import mrs.domain.service.room.RoomService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("reservations/{date}/{roomId}")
public class ReservationsController {
	@Autowired
	RoomService roomService;
	@Autowired
	ReservationService reservationService;
	
	@ModelAttribute
	ReservationForm setUpForm() {
		RservationForm form = new ReservationForm();
		form.setStartTime(LocalTime.of(9, 0));
		form.setEndTime(LocalTime.of(10, 0));
		return form;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	String reserveForm(@DateTimeFormat(iso=DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date,
			@PathVariable("roomId") Integer roomId, Model model) {
		ReservableRoomId reservableRoomId = new ReservableRoomId(roomId, date);
		List<Reservation> reservations = reservationService.findReservations(reservableRoomId);
		
		List<LocalTime> timeList =
				Stream.iterate(LocalTime.of(0, 0), t -> t.plusMinutes(30))
				.limit(24 * 2)
				.collect(Collectors.toList());
		
		model.addAttribute("room", roomService.findMeetingRoom(roomId));
		model.addAttribute("reservations", reservations);
		model.addAttribute("timeList", timeList);
		model.addAttribute("user", dummyUser());
		return "reservation/reserveForm";
	}
	
	private User dummyUser() {
		User user = new User();
		user.setUserId("taro-yamada");
		user.setFirstName("taro");
		user.setLastName("Yamada");
		user.setRoleName(RoleName.USER);
		return user;
	}
}
package mrs.app.reservation;

import java.io.Serializable;
import java.time.LocalTime;

import javax.validation.constraints.NotNull;

import org.springframework.format.annotation.DateTimeFormat;

public class ReservationForm implements Serializable {
	@NotNull(message = "必須です")
	@DateTimeFormat(pattern = "HH:mm")
	private LocalTime startTime;
	
	@NotNull(message = "必須です")
	@DateTimeFormat(pattern = "HH:mm")
	private Localtime endTime;
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title th:text="|${#temporals.format(date, 'yyyy/M/d')}の${room.roomName}|">2021/01/29の豊洲</title>
</head>
<body>

<div>
<a th:href="@{'/rooms/' + ${date}">会議室一覧へ</a>
</div>

<form th:object="${reservationForm}"
	th:action="@{'/reservations/' + ${date} + '/' + ${roomId}}" method="post">
	会議室: <span th:text="${room.roomName}">銀座</span>
	<br>
	予約者名: <span th:text="${user.lastName + ' ' + user.firstName}">山田太郎</span>
	// 省略

うーむ、全体的な流れを掴むには良いが、もう少し入門的なところからやりたい。。