해당 글은 Spring으로 구현한 프로젝트를 SpringBoot로 리팩토링 하는 과정을 담은 글입니다.
이번 시간에는 관리자로 로그인하여 객실 정보를 불러오는 작업을 하려고 합니다.
1. 테이블 구조
테이블은 room, room_image으로 구성되어 있습니다.
객실 정보를 불러올 때 객실 이미지 정보도 같이 불러와서 목록에 노출시켜야 하므로
객실테이블과 객실 이미지 테이블을 조인 시켜줘야 합니다.
2. Entity 선언
** 객실 테이블, 객실 이미지 테이블 관계 **
- 객실 테이블 : 주 테이블
- 객실 이미지 테이블 : 대상 테이블
객실과 객실이미지는 양방향 관계가 되는데 객실이미지 테이블에 외래키 설정이 되어 있다.
이 구조는 외래키에 Null 값이 들어가지 않는다. 객실이미지는 객실이 없으면 존재하지 않는다.
1) Room.java (객실엔티티 - 주 테이블)
package com.boot.sonorous.admin.entity;
import jakarta.persistence.*;
import lombok.Data;
import lombok.ToString;
@Entity
@Data
@ToString(exclude = "roomImage")
@Table(name = "T_ROOM")
public class Room {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ROOM_ID")
private int Id;
private String roomName;
private String roomSize;
private String bedType;
private String roomPrice;
private String roomAmount;
private String peopleNum;
private String roomSpec;
private String insId;
private String insDate;
private String modId;
private String modDate;
@OneToOne(mappedBy = "room")
private RoomImage roomImage;
}
2) RoomImage.java
@Entity
@Data
@Table(name = "T_ROOM_IMAGE")
public class RoomImage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ROOM_IMAGE_ID")
private int Id;
private String roomImageName;
private String roomImagePath;
@OneToOne
@JoinColumn(name="room_id")
private Room room;
}
대상테이블에 외래키를 둬야하기 때문에 @JoinColmn을 객실이미지엔티티에 둡니다.
Room 엔티티에 RoomImage 필드에 mappedBy 속성을 통해 연관 관계의 주인이 RoomImage에 있음을 알립니다.
3. Controller 선언
@Controller
public class SonorousRoomController {
@Autowired
private SonorousRoomService sonorousRoomService;
@GetMapping("/roomList")
public String roomList(Model model, HttpSession session, HttpServletResponse response) throws Exception {
// 1. 세션값이 널이거나
// 2. 관리자 권한이 아니면 로그인 페이지 이동
Member loginMember = (Member)session.getAttribute("loginMember");
if(loginMember == null || !(loginMember.getMAuth().equals("ADMIN"))){
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>alert('접근 권한이 없습니다.');</script>");
out.flush();
out.close();
}
List<RoomImage> roomList = sonorousRoomService.roomList();
System.out.print(roomList);
model.addAttribute("roomList", roomList);
return "admin/roomList";
}
}
서비스에 객실 정보를 불러오는 roomList() 메서드를 호출, 엔티티 타입이 RoomImage인 List에 담습니다.
4. service 선언
@Service
public class SonorousRoomService {
@Autowired
SonorousRoomRepository sonorousRoomRepository;
public List<RoomImage> roomList() {
return sonorousRoomRepository.findAll();
}
}
레퍼지토리에 테이블 모든 컬럼을 조회하는 findAll() 메서드를 호출, List<RoomImage>로 반환합니다.
5. Repository 선언
@Repository
public interface SonorousRoomRepository extends JpaRepository<RoomImage, Integer> {
}
레퍼지토리 인자에 RoomImage 엔티티와 Id 값의 타입인 Integer를 넣습니다.
controller에서 roomList 이름의 리스트에 담고 admin/roomLIst 경로의 view 호출합니다.
6. view 선언
<div id="table">
<table style="margin:auto; text-align:center;">
<caption style="visibility:hidden">카테고리ID, 케테고리명, 사용여부, Description, 등록자 표시하는 테이블</caption>
<colgroup>
<col width="10%"/>
<col width="30%"/>
<col width="40%"/>
<col width="20%"/>
</colgroup>
<tr>
<th align="center">No</th>
<th align="center">이미지</th>
<th align="center">객실이름</th>
<th align="center">등록일</th>
</tr>
<tr th:each="room : ${roomList}">
<td th:text="${room.room.Id}"></td>
<td th:if="${room.roomImageName != null}">
<img style="width: 150px;height:100px" th:src="'/upload/' + ${room.roomImagePath} + '/' + ${room.roomImageName}"/></td>
<td>
<a th:href="'/roomView?Id=' + ${room.room.Id}" th:text="${room.room.roomName}"></a>
</td>
<td th:text="${room.room.insDate}"></td>
</tr>
</table>
</div>
roomList 리스트에 담긴 값을 room에 하나씩 담고 값을 꺼내옵니다.
room(객실 이미지정보) > room(객실 정보)가 있으므로 객실 id를 가져오려면 room.room.Id로 가져와줍니다.
객실 이미지는 /upload/객실이미지경로/객실이미지이름 경로에 있어
src에 위와 같이 작성하면 이미지를 불러옵니다.
참고블로그
https://wildeveloperetrain.tistory.com/186
JPA @OneToOne 일대일 연관 관계 정리 및 LazyLoding 이슈
JPA를 사용하면서도 연관 관계 매핑을 쓰지 않다가 이번 프로젝트에서 연관 관계를 적용하기 시작하며 정리한 내용이며, JPA 연관 관계 매핑 중에서 1:1 연관 관계인 @OneToOne에 대해 정리한 내용입
wildeveloperetrain.tistory.com
'Spring > SpringBoot' 카테고리의 다른 글
[goormedu 강의] 스프링부트 블로그 만들기 02 - 01 stateless란 (0) | 2024.08.05 |
---|---|
[SpringBoot] 호텔예약사이트 - 관리자 객실 등록 (0) | 2024.03.30 |
[SpringBoot] 호텔예약사이트 - 사용자, 관리자 메뉴 구분 (0) | 2024.03.20 |
[SpringBoot] 호텔예약사이트 - 로그인 구현 (0) | 2024.03.10 |
[SpringBoot] 간단한 게시판 생성_페이징처리 (0) | 2024.01.20 |