Users와 Boards Join하기 (2) - Boards Join하기 (Object 생성방식과 ORM 맛보기)

bethe·2022년 9월 4일
0

Springboot

목록 보기
31/46
post-custom-banner

이론

셀렉트 두 번 하는 것보다 조인해서 들고오는게 좋음 I/O가 한번만 일어나니까

user라는 object를 적을 수 있음 (컴포지션해서)

ORM : object끼리 릴레이션을 맺고 매핑할 수 있어요. (오브젝트가 오브젝트를 포함하과 있다 -> 오브젝트끼리 릴레이션을 맺고 있다고 말함)

둘 중 어느 형태든 모델에 담아서 뷰에 뿌리면 끝나~


Entity 만들어서 JOIN 하기

1. Mapper

	<select id="findByIdtoDetail" >
		SELECT b.id, b.title, b.content, b.usersId, b.createdAt,
				u.id, u.username, u.password, u.email, u.createdAt 
		FROM boards b INNER JOIN users u
		ON b.usersId = u.id
		WHERE b.id = #{id}
	</select>

SELECT할 때 무조건 다 들고 오세요
DAO는 DB에 있는 걸 다 들고오고 무엇을 출력할지는 service에서 결정함

근데 문제가 하나 있어
b.id u.id가 id로 return되니까 DB에서
column값에 _1이 붙어서 나중에 매핑이 안됨

사실상

	<select id="findByIdtoDetail" >
		SELECT b.id, b.title, b.content, b.usersId, b.createdAt,
				u.id as userId, u.username, u.password, u.email, u.createdAt 
		FROM boards b INNER JOIN users u
		ON b.usersId = u.id
		WHERE b.id = #{id}
	</select>

인데 userId가 두개 있는 셈 -> b.userId를 지우고 u.id에 별칭을 지어주자

	<select id="findByIdtoDetail" >
		SELECT b.id, b.title, b.content, b.createdAt,
				u.id as userId, u.username, u.password, u.email, u.createdAt 
		FROM boards b INNER JOIN users u
		ON b.usersId = u.id
		WHERE b.id = #{id}
	</select>

(혹은 반대로 해서 u.id(PK)를 쓰지 않고 b.userId를 쓰고 별칭을 안 써도 됨)
createdAt도 중복되어서 삭제.

	<select id="findByIdtoDetail" >
		SELECT b.id, b.title, b.content, b.userId, b.createdAt,
				u.username, u.password, u.email
		FROM boards b INNER JOIN users u
		ON b.usersId = u.id
		WHERE b.id = #{id}
	</select>

나는 이 쿼리를 사용하겠다.

2. 이 데이터를 매핑할 타입 Entity 만들기 (boards에 mapper 패키지를 만들어서 class생성)

  • 위치는 Web이 아닌 Domain
  • Web : clinet랑 통신
  • Domain : DB랑 통신할 때 씀

package site.metacoding.red.domain.boards.mapper;

import java.sql.Timestamp;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class BoardDetail {
	private Integer id;
	private String title;
	private String content;
	private Timestamp createdAt;
	private Integer usersId;
	private String username;
	private String password;
	private String email;
}

result Type 경로 맞춰주기

	<select id="findByIdtoDetail" resultType="site.metacoding.red.domain.boards.mapper.BoardDetail" >
		SELECT b.id, b.title, b.content, b.userId, b.createdAt,
				u.username, u.password, u.email 
		FROM boards b INNER JOIN users u
		ON b.usersId = u.id
		WHERE b.id = #{id}
	</select>

3. 쿼리 때릴 메서드 DAO에 만들기

package site.metacoding.red.domain.boards;

import java.util.List;

import site.metacoding.red.domain.boards.mapper.BoardsDetail;
import site.metacoding.red.web.dto.reqest.boards.WriteDto;

public interface BoardsDao {
	public void insert(WriteDto writeDto);
	public Boards findById(Integer id);
	public List<Boards> findAll();
    //나중에 findAll할 때도 join해서 받아야 할 것임
    //왜냐면 userId가 아닌 작성자 정보를 줘야 하기 때문에
	public void update(Boards boards);
	public void delete(Integer id);
	public BoardsDetail findByIdtoDetail(Integer id);
}

4. Controller

//	@GetMapping("/boards/{id}")
//	public RespDto<?> getOne(@PathVariable Integer id){
//	return new RespDto<>(1,"한건조회성공",boardsDao.findById(id));
//	}
//같은 기능을 하기에 기존의 getOne을 삭제(주석처리)
//하지만 findById자체는 필요함 (update 때 영속화를 하기 위해 사용하기 때문)

	@GetMapping("/boards/{id}")
	public RespDto<?> getOne(@PathVariable Integer id){
	return new RespDto<>(1,"한건조회성공",boardsDao.findByIdtoDetail(id));
	}

insert한 Boards 값이 없어서 해줬다

=> 모델에 담았다면 모델의 key값.code= 1
이렇게 뿌리고 싶은 것만 뿌리면 됨

ORM(Object Relational Mapping)
객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 것을 말한다.

profile
코딩을 배우고 기록합니다. 읽는 사람이 이해하기 쉽게 쓰려고 합니다.
post-custom-banner

0개의 댓글