What I Learned

[NBCAMP | Spring 6기] 42일차 TIL + OOP, JPA, FetchType, ddl-auto

ㅇ달빛천사ㅇ 2024. 8. 28. 11:20
728x90

👈  이전글

[NBCAMP | Spring 6기] 41일차 TIL + TYPE / REGEXP() / FILTER, JWT, Entity, RELATION


KDT 실무형 스프링 백엔드 엔지니어 양성과정 6기

 


🗝 오늘의 학습 키워드 : OOP JPA FetchType ddl-auto



📖 공부한 내용 본인의 언어로 정리하기

 

🚩 SQL 코드카타

🗨️ Revising the Select Query I

 

Revising the Select Query I | HackerRank

Query the data for all American cities with populations larger than 100,000.

www.hackerrank.com

 

오늘 처음으로 HackerRank SQL 문제가 나왔다.

HackerRank에서는 처음이라 그런지가 난이도가 최하였다.

특이한 것이 테이블은 안보여주고 테이블의 칼럼명과 타입만 보여주고 문제를 풀어라고 함.

 

💡 Oracle & MySQL

SELECT *
FROM CITY
WHERE COUNTRYCODE = 'USA'
      AND POPULATION > 100000;

오늘의 회고

오늘은 정규 내배캠 10분 전에 CS 스터디를 하였다.
민혁님께서 뽑기에 1등 당첨되셔서 첫번째로 발표하셨는데 OOP에 대해
구체적으로 잘 설명해 주셨다.
아침을 CS 스터디로 시작하니 또 다른 기분이 들었다.
발표가 조금 길어져서 코드카타 시간을 잡아 먹긴 했는데
OOP에 대한 설명을 제대로 정리하지 못한 부분이 있어 깃허브 링크에 접속하여
조금 더 내용을 읽어보고 코드카타를 시작하였다.
알고리즘 코드카타는 데일리 루틴에 있는 것은 모두 해결하였기 때문에 SQL 코드카타부터 풀었다.
그런데 Hackerank에서 처음으로 나온 문제라 그런지 난이도가 왕초보 입문급이었다.
너무 쉬워서 요즘 어려운 문제 해결하는 것에 재미가 들어있던 나에게는 약간 실망이었다.
차라리 앞쪽부분에 넣어두지 왜이렇게 뒤쪽에 이렇게 쉬운 난이도를 둔 걸까?
알고리즘 코드카타를 못하는 것이 아까워서 LeetCode에 들어가서 문제를 풀었다.
다익스트라 문제였는데 해결하지는 못하였지만 아침시간에 알고리즘을 풀기위해 머리를 조금 더 굴린 것에 의의를 두기로 했다.

오전에 스탠다드 실습반 강의를 들었다.
연관관계 및 지연로딩 등에 대해 배웠다.
예전에는 강의내용이 내가 듣는 인강보다 조금 느린 느낌이었는데
이제는 거의 같은 내용을 다루고 있어서 강의 듣는 속도를 조금 더 빨리해야겠다는 생각이 들었다.
연관관계관련 뒷부분 강의를 못 들은 부분이 있어서 마저 듣고 저녁이 되어서야 과제를 시작할 수 있었다.
API 쓰고 ERD 그리는 것에 생각보다 많은 시간이 들어갔다.
처음부터 코드를 작성하려다가 예전에 개인과제 한 내용과 비슷하여
그 코드를 업그레이드하기로 하였다.
튜터님께서도 그렇게 해도 된다고 하셨으니^^
README 파일도 정리하면서 코드를 열심히 썼는데
막상 처음 코드를 돌리려고 하니 계속 에러가 떴다.
혼자서는 해결이 안되어 아무래도 튜터님께 도움을 요청해야할 것 같다.
저녁에는 호진님께서 전날 알고리즘 코드카타 물어보셨던 내용을 블로그로 정리한 것도 보여주시고
사각형 문제의 풀이가 이해가 안된다고 하여 같이 풀이를 보았는데
코드가 내가 쓴것의 거의 4분의 1 수준으로 짧았다!
와우! 이렇게 짧게 풀 수 있는 문제였다니!!!
그런데 그 풀이가 나온 이유는 나도 이해가 잘 안되어서 
예전에 봤던 수학 심화 문제랑 비슷한 느낌이 들어 찾아보았는데
사각형을 밀어서 해결하면 정말 간단한 풀이가 나오는 것이었다!
오늘도 또 한번 개안을 하였다.
호진님은 뭔가 어렵다고 말씀하시면서 엄청 간단하게 술술하시는 느낌이라
나도 많이 배우고 싶은 느낌이 든다.
호진님과 이야기를 더 많이 나누고 싶었지만 과제를 해야했기에 수다를 끊고 과제를 하였다.
근데 아무리 찾아봐도 에러가 해결이 안되고 너무 피곤해서 그냥 일찍 잠들었다.ㅜㅜ
8시에 일어나서 오늘도 다음날 쓰는 TIL이 되어버렸다.
오늘은 꼭 필수요구사항 다 구현하고 자야지!

 

🗨️ 무엇을 새롭게 알았는지

🌄 하루 10분 CS 스터디

객체 지향 프로그래밍 (OOP; Object Oriented Programming)

 

객체지향 프로그램을 만들기 위해서 고려해야할 것들

  • 프로그램에 어떤 객체들이 필요할 지 정한다.
  • 객체들의 속성과 행동들을 정한다.
  • 객체들이 서로 어떻게 소통해야할 지 정한다.

강한 응집력  & 약한 결합력

  • 응집력(Cohesion)
    • 프로그램의  한 요소가 해당 기능을 수행하기 위해 얼마만큼의 연관된 책임과 아이디어가 뭉쳐있는지를 나타내는 정도
    • 프로그램의 한 요소가 특정 목적을 위해 밀접하게 연관된 기능들이 모여서 구현되어 있고, 지나치게 많은 일을 하지 않도록 하여 응집력을 높인다.
  • 결합력(Coupling)
    • 프로그램 코드의 한 요소가 다른 것과 얼마나 강력하게 연결되어 있는지, 얼마나 의존적인지를 나타내는 정도
    • 클래스 간에 돍립적으로 디자인 함으로써 결합력을 약하게 할 수 있다.

기본 구성 요소

  • 클래스(Class)
    • 같은 종류의 집단에 속하는 속성과 행위를 정의한 것
    • 다른 클래스와 독립적으로 디자인
    • 예시 ) 몬스터
  • 객체(Object)
    • 클래스의 인스턴스
    • 상위 클래스의 속성을 가지고 있으면서 개별적인 특성과 행위 또한 가지고 있다.
    • 예시 ) 오우거, 드래곤, 좀비 등..
  • 메서드(Method)
    • 클래스 로부터 객체를 사용하는 방법
    • 객체의 속성을 조작하는 데 사용
    • 예) 레벨업

  • 캡슐화(Encapsulation)
    • 객체의 데이터를 외부에서 직접 접근하지 못하도록 차단  (예. Getter/ Setter, private 접근 제어자)
    • 속성과 이 속성을 사용하는 행동을 하나로 묶어야 함. (객체를 사용할 때는 메서드를 사용)
  • 추상화 (Abstraction)
    • 객체들이 가진 공통 특성들을 파악해서 불필요한 특성을 제거하는 과정
    • 속성 위주가 아닌 동작 위주(메서드)로 정의
    • 이름 지정 및 문서화를 잘 하여 구조를 상세히 몰라도 클래스나 메서드 변수들의 이름만으로 파악 가능하도록 하자.
  • 상속(Inheritance)
    • 중복되는 코드는 상속받는다.(부모 클래스를 만들어 오버라이드하여 활용)
  • 다형성(Polymophism)
    • 하나의 클래스가 다양하게 쓰이는 것 (같은 메서드를 호출해도 객체에 따라 내용이 달라지는 개념)

참고) 오버로딩 vs 오버라이딩

  • 오버로딩 : 같은 이름의 함수를 매개변수의 타입, 개수를 다르게 하여 재정의 한 것
  • 오버라이딩 : 부모 클래스에서 정의한 메서드와 같은 이름, 같은 매개변수를 갖는 메서드를 자식 클래스에서 재정의한 것

장점 및 단점

  • 장점
    • 재사용성 : 한번 작성된 코드를 바로바로 가져다 쓸 수 있다.
    • 유지 보수 및 업그레이드가 쉽다.
    • 대형 프로젝트에 효과적
    • 직관적인 코드 분석 가능
  • 단점
    • 처리 속도가 느리다.
    • 객체가 많아질수록 용량이 커진다.
    • 설계 시, 시간과 노력이 많이 필요하다.

SOLID

  • 단일 책임 원칙 : 모든 클래스는 가각 하나의 책임만 가져야 한다. >> 그 책임을 완전히 캡슐화 해야 함.
  • 개방 - 폐쇄 원칙 : 확장에는 열려있고 수정에는 닫혀있어야 한다.
    • 기존 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계가 되어야 한다.
    • Getter, Setter(수정 개념이므로 Setter 사용을 마구 하면 안됨.)
  • 리스코프 치환 원칙 : 자식 클래스는 언제나 부모 클래스를 대체할 수 있다.
    • 자식 클래스는 부모 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행하도록 해야한다.
  • 인터페이스 분리 원칙 : 한클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다.
    • 하나의 일반적 인터페이스보다 여러개의 구체적 인터페이스가 좋다.
  • 의존 역전 원칙 : 의존 관계를 맺을 때 변화하기 어려운 것에


🍀 스탠다드 실습반

JPA(Java Persistence API)

  • 자바 진영의 ORM 기술
  • 객체 지향적으로 데이터 베이스 조작 가능
  • Application과 JDBC 사이에서 동작
  • 직접 SQL 대신 Entity를 가지고 DB 작업
  • Entity는 영속성 컨텍스트에서 관리


@Entity : 기본 생성자 (생략 불가)
DB 데이터를 Entity로 변환할 때, Reflection이라는 기능을 사용하는데 이 때, 기본 생성자를 사용

protected 생성자 : 기본 생성자를 외부에서 사용 불가하도록, 정해진 방법대로 해당 Entity를 생성하도록 함.
통일성 있게 Entity 코드를 작성할 수 있음.
코드 작성할 때, 무분별하게 생성자를 생성하지 않았는지 점검하기!

@Id: PK 값 설정
@GeneratedValue(startegy = GenrationType.IDENTITY) : AUTO INCREMENT로 PK값 설정


단방향 MAPPING

1:N 관계 @ManyToOne
연관 관계를 @JoinColumn(name "course_id")으로 설정 

(이 때, name 속성값은 상대 Entity의 @Column(name = "course_id") 의 속성값으로 주는 것! 필드 변수명x)


지연로딩 FetchType

  • LAZY : 일단 회원만 조회하고 관련된 정보는 필요할 때, 따로 조회 (권장!)
  • EAGER : JPA 기본 조회 전략(default값)
    • 회원(member) 조회 시점에 관련된 모든 수업(course) 데이터도 함께 조회
      (EAGER로 설정하면 데이터 부하가 걸려서 프로젝트 진행이 어려움)


@Column(name ""nullabletrue/falselength=00columnDefinition = "TINYINT(1) DEFAULT 0")


[ 양방향 연관 관계 ]

@OneToMany(mappedBy = "상대 Entity의 필드 변수명")

 


[ 양방향 연관 관계 사용하지 말라!는 말을 하는 이유 ]

  • 순환 참조 : 서로 객체가 양방향으로 참조하다보면 순환 참조 오류 발생
    • 무한 루프에 빠지거나 애플리케이션이 멈출 수 있는 심각한 에러
  • 구현 복잡도 : 한쪽 Entity에서 변경이 발생할 때마다 다른쪽 Entity에서도 해당 변경을 반영해야 함.

 

양방향 관계를 설정할 수 있으면 "최대한 단방향으로 설계"하여 개발하는 것이 좋음.
(코드 복잡성 감소 및 유지보수를 간단히 하기 위해 양방향 연관관계는 정말정말정~말로 필요한 경우에만 사용합시다.)


[ 자동 테이블 설정(ddl-auto) ]

: 개발 초기 단계에는 Entity 클래스가 자주 변경됨.

  • ddl-auto 옵션을 사용하면 Entity에 맞는 테이블 생성 가능

(운영 환경에서는 이 속성을 사용하지 않는 것을 권장!

create, update 등 속성이 동작하면 데이터가 전부 삭제되거나 큰 장애로 이어짐.)

spring:
  jpa:
    hibernate:
      ddl-autocreate

 

  • create : 애플리케이션이 시작될 때, 모든 테이블 삭제 후, 새로 생성
  • update : 기존 테이블 필드 유지, 변경 사항만 반영
    • 데이터 손실 없이 기존 데이터베이스 구조를 유지하면서 업데이트가 필요한 경우에 주로 사용
  • create-drop : 애플리케이션 시작시 테이블 생성. 그리고 종료시 테이블 제거
    • ex) 주로 통합 테스트 및 임시 테스트 환경에 사용
  • Validation : 애플리케이션 Entity 모델과 DB Schema가 일치하는지 검증 후, 일치하면 실행. if not 실행 x

 

[ Repository 만들기 ]

  • 순수 JPA 기반 Repository
    • EntityManager를 직접 케어(생산성 저하), 커스텀한 데이터 베이스 접근 로직 구현 가능
    • 생산성 저하 : 반복적이고 일반적인 데이터 접근 로직을 직접 구현
  • JPA 인터페이스 기반 Repository
    • 생산성 향상 : 대부분의 기본적인 데이터 접근 로직 이미 구현
    • 유연성 부족 : JPA의 기본 동작을 변경하거나 세밀한 제어가 어려움.

[ N + 1  문제 식별하기 ]

  • JPA와 같은 ORM 도구를 사용할 때, 발생하는 성능 문제
  • 하나의 쿼리를 수행한 후에 추가로 N개의 쿼리가 발생하는 상황

[ N + 1 문제 해결 방법 ]

Fetch Join

  • 연관된 Entity를 함께 가져오도록 만들어 추가적인 쿼리가 발생하지 않음.
  • 쿼리 실행 횟수가 줄어들면서 DB 통신횟수 감소 >> 성능 향상
    (특히 많은 양의 데이터를 다루는 경우 성능 차이가 더욱 크게 나타남)

JPQL 작성
@Query("SELECT c  FROM COURSE c JOIN FETCH c.member")
List<Course> findAllWithFetchJoin();



💭 내일 학습할 것은 무엇인지

  • 개인과제 필수 요구 사항 구현 완료





👉  다음글







 

728x90