team과 game을 N:1 관계로 하고 싶었는데, 스키마를 짜다가 실패했다. mapping table을 하나 더 만들어보기도 하고 이리저리 시도해보다가 잘 안되어서 그냥 game 테이블을 따로 두고, team과 관계설정을 안 맺도록 했다. game의 컬럼들이 team의 id를 갖고 있는데 관계설정이 안되어있어서 굉장히 이상해보이는데 이 이상의 방법이 떠오르지 않는다.
record 조회하기, record가 member를 참조? member가 record를 참조?
{
"teamId": 1,
"records": [
{
"name": "나지완",
"position": "타자",
"atBat": 3,
"hit": 1,
"out": 1,
"average": 3.0
},
{
"name": "김유신",
"position": "타자",
"atBat": 3,
"hit": 1,
"out": 1,
"average": 3.0
}
]
}
위와 같이 record를 조회할 때 API상으로는 member의 name을 포함하는게 자연스러워보인다. 근데 Record 도메인 클래스에다가 member의 name을 필드로 갖게 되면 디비 설계상으로 member가 record를 참조하도록 해야하는데 이게 뭔가 어색했다. member가 record를 참조한다면 스키마는 이렇게 될 것이다.
create table member
(
id int primary key auto_increment,
name varchar(45),
position varchar(45),
team int references team (id),
record int references record (id)
);
create table record
(
id int primary key auto_increment,
at_bat int,
hit int,
`out` int,
average double
);
record가 id값을 가지는 것이 어색해보이고, record가 member를 참조하는 방향이 더 올바르다고 생각된다. 계속 이부분이 헷갈리는데 record가 id를 갖는게 맘에 들지 않았다.
그래서 아래와 같이 바꿨다.
create table member
(
id int primary key auto_increment,
name varchar(45),
position varchar(45),
team int references team (id)
);
create table record
(
at_bat int,
hit int,
`out` int,
average double,
member int references member (id)
);
record가 member를 참조하도록 변경했다.
그래서 위의 JSON형식과 같이 name을 포함하게 하려면 join을 사용해야할 것 같았다.
public interface TeamRepository extends CrudRepository<Team, Long> {
@Query("select at_bat, hit, `out`, average, name, position from record left join member
on record.member = id where id = :id")
Optional<RecordMember> findRecordByMemberId(Long id);
}
위와 같은 메소드를 선언해주고 join 쿼리문을 작성하고, RecordMember라는 클래스를 만들었다.
이렇게 해주니 내가 원하는대로 잘 나왔다.
내일