[TIL] 26일차 _ 숙련 Spring #2, 일정관리 앱 Dev #1

Seoyeon Lee·2025년 11월 10일

Today I Learned ...

오늘은 코드카타 SQL과 알고리즘 33-35번 문제를 풀고, 숙련 Spring 강의를 끝내고, 일정관리 앱 Dev 과제를 시작했다!


🗒️ 코드카타 #19

오늘 진행한 SQL 문제들은 지난 문제에 이어 join을 활용해 두개의 테이블을 연관지어 데이터를 가공하는 것이었다.
오늘은 두 테이블의 날짜 비교를 하는 문제가 많았는데, 날짜에도 비교연산자를 사용할 수 있다는 사실을 알게 되었다!
비교연산자를 사용하지 않고 날짜 비교를 한다면 datediff를 사용해 계산된 값이 양수인지 음수인지를 따져볼 수 있을 것 같다.

오늘은 총 3개의 알고리즘 문제를 풀었는데,
첫 번째 문제는 약수의 개수가 짝수인 수는 더하고, 홀수인 수는 뺀 값을 계산하는 것이다.
이전에 약수를 구하는 문제를 풀어본 적이 있어 어렵지 않게 해결할 수 있었다.
그런데.. 사실 약수의 개수가 홀수인 경우는 어떤 수의 제곱인 경우밖에 없기에... 제곱근을 구하는 Math.sqrt()를 활용해 제곱수인 경우만 찾으면 되는 것이었다.
역시 똑똑해야 뭐든 하나보다..

두 번째 문제는 문자열을 내림차순으로 배치하는 것이었다.
처음에는 문자열을 char 배열로 바꾸고, 그걸 아스키코드 값으로 바꾸고, 내림차순으로 정렬하고, 다시 char 배열로 바꾸고, 문자열로 합치는 방식으로 했다.
근데 알고보니 sort로 문자열도 정렬할 수 있었다...!
그래서 sort를 활용해 간단하게 다시 해결했다...

마지막으로 세 번째 문제는 지불해야 할 금액을 계산하고, 가지고 있는 돈에서 얼마나 부족한지를 계산하는 것이었다.
계산 자체는 큰 어려움 없이 해결할 수 있었다.
가지고 있는 돈이 내야 할 금액보다 많은 경우에는 0을 반환하라는 조건이 있었는데, 나는 이걸 if문을 활용해 해결했다.
그런데, 다른 사람의 풀이를 보니 두 값 중 큰 값을 반환하는 Math.max()를 사용하면 if문 없이도 해결할 수 있었다.
가급적.. 생각이라는 것을 좀 해보도록 해야겠다.

각각의 문제와 풀이는 깃허브를 통해 업로드해두었다.
GitHub 보러가기


📚 숙련 Spring #2

오늘은 3주차 강의를 들으며 숙련 Spring 강의를 완강했다!

3주차의 주된 내용은 2개의 엔티티를 매핑하는 것이었다.

엔티티를 매핑은 크게 2가지 종류로 나눌 수 있는데, 한쪽에서만 다른 쪽을 참조하는 '단방향 관계'와 서로를 참조하는 '양방향 관계'이다.
그치만 사실 양방향 관계는 꼭 필요한 경우가 아니라면 사용하지 않는다고 한다.

엔티티 간의 관계는 4가지 종류가 있는데, 일대일 관계, 일대다 관계, 다대일 관계, 다대다 관계로 나눌 수 있다.

먼저, 일대일 관계는 말 그대로 엔티티가 일대일 관계로 대응된다는 것이다.
@OneToOne 어노테이션을 사용해 구현할 수 있는데, 여기에서 중요한 것은 누가 외래 키를 관리할 것이냐는 문제이다.
외래 키는 '주도 테이블'이 관리하도록 하는 것을 추천하는데, 예를 들어, member와 profile이라는 테이블을 매핑한다면 사람인 member 테이블에서 관리하도록 하는 것이다.

두 번째로, 다대일 관계는 '다수'에서 '단일'을 참조하는 관계로, 사실상 모든 관계의 핵심이다.
예를 들어, team 테이블과 member 테이블이 있다면 다수의 member가 하나의 team에 들어가는 관계인 것이다.
이때 member가 team을 선택하는 것이기에 이 관계의 주인은 member가 되고, 관계의 주인인 member가 team id의 외래 키를 관리하도록 해야한다.
다대일 관계는 @ManyToOne 어노테이션을 사용해 구현할 수 있다.

세 번째로, 일대다 관계는 '단일'에서 '다수'를 참조하는 관계로, 위의 예시에서 사용했던 team 안에 member의 리스트가 존재하는 형태이다.
일대다 관계는 다대일 관계가 존재할 때만 존재할 수 있고, @OneToMany 어노테이션을 사용해 구현할 수 있다.
하지만, 테이블의 한 칸 안에 리스트가 들어가는 것은 데이터베이스의 입장에서는 불가능한 일이기에 사용하지 않는 것을 추천한다.

마지막으로, 다대다 관계는 '다수'와 '다수'를 매핑하는 것으로, 예를 들자면 하나의 책에 여러 명의 저자가 있고, 한 명의 저자는 여러 권의 책을 집필하는 것과 같다.
이는 @ManyToMany 어노테이션을 사용해 구현할 수 있는데,
한 칸에 리스트가 들어갈 수 없다는 이유와 더불어 실제로 DB를 생성하면 코드로 관리할 수 없는 중간 테이블이 생기기 때문에 사용하지 않는다고 한다.
그 대신 Author 테이블과 Book 테이블을 각각 만들고, AuthorBook이라는 중간 테이블을 새롭게 만들어 여기에서 @ManyToOne 관계로 구현하는 방법을 사용한다.

이외에도 영속성 전이와 JPQL 사용 방법, JPQ 테스트 방법 등에 대해서도 다루고 있으나
실제 현업에서는 잘 사용하지 않고, 이번 과제에서 다루지 않는 내용들도 있기에 더 자세히 정리하지는 않도록 하겠다.

강의의 자세한 설명은 노션에 정리해두었다.
Notion 확인하기


🖥️ 일정관리 앱 Dev 프로젝트 #1

오늘은 일정관리 앱 Develop 과제를 시작했다!
사실 시작했다고 하기엔... 프로젝트 생성하고 Lv.1의 1번까지 구현한게 다이지만...

일정 생성 API를 구현하면서 생성 API와 수정 API의 다른 점이 무엇인지가 궁금해졌다.

수정 API를 구현할 때는 modifiedAt이 제대로 변경되지 않고 이전 값이 출력된다는 문제가 있었는데,
이는 modifiedAt은 트랜잭션이 commit 된 후에 변경되고, 나는 트랜잭션을 끝내기 전에 return으로 객체를 불러왔기 때문이었다.
그래서 트랜잭션이 끝나기 전에 modifiedAt을 변경하기 위해 setter를 사용하거나 saveAndFlush를 사용해야만 했다.

그런데, 사실 save를 할 때도 트랜잭션이 끝나기 전에 return으로 객체를 불러오는데 왜 이때는 modifiedAt이 잘 적용이 되는 것인지 궁금해졌다.
알고보니 modifiedAt이 생성되는 시점은 트랜잭션이 commit되는 시점이 아니라 modifiedAt을 사용하는 객체가 new를 통해 생성될 때였다.
그래서 new로 일정 객체를 생성할 때 createdAt과 modifiedAt이 생성된 것이고, 그게 그대로 return으로 가져와진 것이다.
즉, modifiedAt의 초기화 시점은 트랜잭션과 상관이 없었던 것이다!!

과제를 하다가 이상한 데에 꽂혀서 이 이상의 진도는 나가지 못했지만...
그래도 과제 제출 기한이 한참 남았으니 내일부터 다시 열심히 해봐야겠다.


🙃 오늘의 느낀점

확실히 일정관리 앱 과제를 한번 끝내고 새로운 강의를 들으니 강의가 생각보다 재미있었다.
강의를 듣는 내내 아 이거 필요했었는데!! 생각하면서 들었다.
이런저런 코드를 다 써가며 구현했던 내용들, 구현하다 결국 포기한 내용들이 다 어노테이션 하나로 쉽게 해결될 문제였다.

강의를 들으면 들을수록 궁금해지는 것들만 잔뜩 쌓여간다.
오늘 이것저것 다 여쭤보며 궁금증을 해소했지만.. 너무 많은 것들을 궁금해하고있나 싶기도 하다.
너무 깊게 빠지지는 말고 할건 하면서 찾아봐야겠다.

profile
백엔드 개발자 지망생

0개의 댓글