재학습/JPA

ID생성전략 없이 Custom String ID를 만들어보자!

재이든 2021. 7. 26. 00:36
반응형

[기술 스택]

SpringBoot + Postgresql + JPA

 

[기존 ID생성 전략]

JPA에는 3가지 전략 존재한다.

3가지 전략에 대한 간단한 설명은 아래 글에서도 언급했으니 넘어간다.

 

https://japing.tistory.com/entry/기본키-매핑전략-Identity에-대해

 

기본키 매핑전략 Identity에 대해

JPA의 기본키 매핑전략에는 총 3가지가 있다! 1.Identity -DB에게 ID생성을 맡기는 방법! 2.Sequence -시퀸스를 이용하여 ID를 증가시키는 방법! 3.Table -시퀸스처럼 사용할 수 있는 테이블을 생성하여 ID를

japing.tistory.com

 

이번프로젝트에서는 직접 아이디를 만들어 주입하는 방식을 사용한다.

즉, ID Generator을 사용해서 ID를 배정하는게 아닌,

개발자가 직접 아이디를 집어넣은 후 Persist하여 DB에 반영하는 로직이다.

 

[나의 Custom String ID 생성전략]

ID를 직접 생성해줄때에도 어떤식으로 고유하게 해줄지 고민을 하다가

아래의 방식으로 ID전략을 세웠다.

Team테이블이라면 Team1, Team2, Team3

Team의 하위 개념인 Member테이블이라면, Team1.Member1, Team2.Member2, Team2.Member3

즉, Depth에 따른 Table명 + 숫자ID의 조합이다.

 

[설계]

따라서 나는 시퀸스 테이블을 활용하기로했다.

1.시퀸스테이블을 만든다.

2.Entity를 생성할 시에 시퀸스 테이블로부터 다음 ID 숫자 값을 가져온다

3.가져온 ID값과 테이블명을 조합하여 고유 StringID를 만든 후( ex. Team1) Entity의 ID로 할당한다.

4.해당 Entity를 Persist.

 

**

그리고 Team1.Member4 처럼 Depth를 표현하는 로직은 간단하다.

Member를 생성하는 로직에는 해당 save로직의 파라미터로 'Team1'라는 팀아이디를 넘겨주면 되기 때문이다.

따라서 결과적으로 Team1 + Member + 4 (Seq테이블로부터 얻어온 아이디값) 으로 표현이 될 수 있다.

아래의 소스코드에서 직관적인 해석이 가능할것이다!

 

[개발]

1.시퀸스테이블 생성

 

CREATE SEQUENCE seq_team;

 

2.시퀸스테이블로 부터 조회

 

SELECT nextval('seq_team');

 

나는 JpaRepository를 이용하기때문에 'NativeQuery를 어떻게 쓰지?'라는 궁금증이 생겼으나,

바로 해답을 찾을 수 있었다.

 

class MemberRepository extends JpaRepository{
  @Query(value = "SELECT nextval('seq_team')", nativeQuery = true)
  String getIdFromSeq();
}

 

위와같이 Repository클래스 내에

시퀸스 조회 메서드를 작성한 후

nativeQuery를 true로 설정하고 @Query를 통해 쿼리문을 작성해주면 된다.

 

그리고 설계해준 대로 Service로직을 개발해보면 다음과 같다.

 


@Service
class MemberService{
  Member save(String teamId){
      Team team = teamRepository.findById(teamId);

      String nextId = memberRepository.getIdFromSeq();
      String memberId = Member.getMemberIdByNextIdAndTeamId(nextId, teamId);
      Member member = Member.of(memberId, team);

      memberRepository.save(member);
  }
}


-------

@Entity
class Member{
 public static String getMemberIdByNextIdAndTeamId(String nextId, String teamId){
 	return teamId + "." + "member." + nextId;
 }
}

 

 

반응형

'재학습 > JPA' 카테고리의 다른 글

JPA 필요없는 쿼리가 나간다?  (0) 2021.07.21
기본키 매핑전략 Identity에 대해  (0) 2021.07.18