본문 바로가기
회고

TIL_210526

코동이 2021. 5. 27.

1. Facts(사실, 객관)

- JPQL. Criteria, QueryDSL, NativeSQL, JDBC 차이점 공부

- JPQL 연관관계 조인 공부

- JPQL on 활용 조인 공부

- JPQL 타입변환 공부

- 템플릿 메소드 디자인 패턴 공부

- 스트레티지 패턴 공부

- 클린코드 12장 창발성

- 애완견 중고마켓 html, css, bootstrap 만들기

2. Feelings(느낌, 주관)

- 내가 무심코 JPA를 단순하게 사용했던 것을 넘어서 어떻게 연관관계를 제대로 사용하는지 배우고 있습니다. 강의만 듣고 끝내서 까먹지 않도록 꼭꼭꼭 직접 실습해서 공부할 생각입니다

 

- 클린코드 12장을 읽고 중복제거를 생각해봅니다. 가끔씩 디자인 패턴을 소개하는데, 여기서도 어김없이 템플릿 메서드패턴이 나옵니다. 결국 패턴에 목숨걸게 아니라 인터페이스, 추상클래스를 적절하게 활용하는게 핵심이라고 생각합니다. 다행히 웹을 공부하면서, 코드숨을 통해 DIP을 학습했더니 의존성 주입관계에 이해가 쉬웠습니다.

 

- html,css, boostrap을 통해서 화면 설계를 했습니다. bootstrap 학습이 도움이 되는 것은 아니지만, 어차피 저는 백엔드에 주력하다보니 크게 신경쓰지 않았습니다. 혼자서 낑낑대면서 만드는 것보다 기존의 템플릿들을 적절히 활용해서 조합하니 훨씬 보기 깔끔하고 멋있게 바꼈습니다. 

3. Findings (배운 점)

-실무에서는 JPQL, QueryDSL로 95% 이상의 문제가 해결된다. 하지만 한계가 있어 Native Query, JDBC, JdbcTemplate을 이용해서 해결해야 한다.

 

* 객체지향형 쿼리

*JPQL : 엔티티 중심개발이다. JPA가 SQL을 추상화하여 JPQL이라는 객체지향 쿼리를 제공한다

*Criteria : 동적쿼리에 굉장히 강하고 compile 시 오류를 잡아주지만 가독성이 떨어지고 유지보수가 어렵다

*QueryDSL : 동적쿼리에 강하고, 자바코드로 작성이 강하다. compile 시 오류를 잡아주어 실무에 편하다

*Native Query : JPQL로 해결할 수 없는 특정 DB들의 문제를 해결한다( 오라클 connect by), 특정 DB SQL 힌트

*JDBC & JdbcTemplate : JPA에 관련되지 않기 때문에 영속성 컨텍스트를 강제로 플러쉬해주어야 한다.

 

*조인

-JPQL에서 엔티티와 연관관계를 모두 조회하고 싶을 떄 다음과 같이 조인한다

SELECT m FROM Member m JOIN m.team t

이제 Member 엔티티와 더불어 연관관계로 있는 Team 엔티티까지 같이 조회가 가능하다

연관관계 조인일 때 LEFT JOIN 이후 Team t 가 아니라 m.team t 이다.

 

- JPQL에서 조인 시, 연관관계와 더불어 조건을 더 걸고 싶으면 on을 활용한다,

SELECT m FROM Member m LEFT JOIN m.team t on t.name='A';

이제 Team 엔티티에서 name'A'것만 조회가 된다. 

 

해당 JPQL은 SQL로 다음과 같다

SELECT m.* FROM Member m LEFT JOIN Team t 
ON m.id = t.id and t.name='A';

연관관계이지만 SQL은 테이블 기준이므로 항상 LEFT JOIN 이후 Team t 라는 테이블 명이 나온다

 

- JPQL은 FROM절에 서브쿼리를 사용할 수 없다. 따라서 조인을 하거나, 2번 쿼리를 호출하고 어플리케이션에서 적절하게 수정을 해야한다

 

- 템플릿 메서드 패턴

템플릿 메서드 패턴은 일정한 절차가 있는 프로세스들 중에 구현이 변경 가능한 상황일 때 사용한다.

A,B,C의 순차적인 작업이 있는데, B가 변경의 여지가 있다면 B는 상속받아 구현하고 A 와 C는 고정시킨다.

 

이를 통해 중복을 제거할 수 있다. 만약에 패턴을 쓰지 않으면 경우에 따라 (A,B,C) ( A,B',C) (A,B''C) 의 모양을 가지게 되어 A,C는 계속 중복된 코드로 남아있을 수밖에 없다

 

해결책은 (A,B,C)를 D라는 메서드 안에 묶고 interface에 정의한다. 구체적인 케이스에 따라서 interface를 구현하면 되는데, 특히 D메서드의 B의 코드를 요구사항에 맞게 짜면 된다. interface에 미리 공통적인 부분을 private A, private C 메서드를 사용하여 정의한다면 어떠한 곳에서도 수정이 불가능하다. B는 protected B로 선언하여 상속받은 클래스에서만 수정이 가능하도록 하여 구현하면 된다.

 

예를 들어, 게임 접속을 위해 인증, 인가, IP검사 등을 하는 절차를 거친다고 하자. 한국은 10시에 게임이 꺼지는 셧다운제를 실시하므로 한국 계정은 접속 시 10시 이전인지 이후인지 확인하여 강제종료를 해야한다. 그렇다면, IP에 따른 접속시간을 검사하는 부분이 변경 가능한 부분이고, 이외에 본인을 인증하는 부분은 고정부분이다.  

 

이 방법도 엄청난 디자인 패턴이라고 생각하기 보다, 중복된 코드를 줄이고자, 일정한 절차 중에 변경 가능한 부분을 interface로 만들어둠으로써 리팩토링이 되는 느낌으로 생각하면 좋을 것 같다

 

- 스트레티지 패턴

 스트레티지 패턴이란, DIP가 정말로 빛을 바라는 패턴이다. 역시나 interfcae를 사용하며, 핵심은 행위를 "위임"하는 것이다. 인터페이스로 변수든, 메서드를 선언해서 이후 구체적인 객체를 선언하여 행위의 다양성을 줄 수 있는 부분이다.

 

 예를 들어,캐릭터의 "공격" 기능을 만든다고 하자. 공격 무기로는 칼, 검, 총이 올 수 있다. 이것을 각각 메서드로 만든다면 3개의 메서드가 필요하다. 하지만 무기라는 interface를 사용하고 그 안에 "공격" 메서드를 만들어 둔다면, 내가 원하는 때에 구현하여 칼, 검, 총을 대입하여 사용하면 된다. 즉, 캐릭터는 칼, 검, 총 객체의 "공격"을 직접 사용하는 것이 아니라, 무기 interface에 있는 "공격"을 사용한다고 정의해 둠으로써 상황에 따라 구체적인 칼, 검, 총 객체에게 "공격" 행위을 "위임"한다.

 

 또한 위임은 웹에서도 많이 쓰이는데, Service 계층에서, 단지 Service는 도메인에게 행위를 위임하도록 구현한다. 이것을 도메인 편의 메서드 방식이라고 불리는데, 기존에 서비스에 많은 로직들을 넣어두는 대신, 도메인을 변경하는 모든 행위는 도메인에서 해결하도록 "위임"하는 것이다. 

 

* JPQL 타입표현

문자 : 'HELLO' , 'SHE''S' (작은 따옴표)

Boolean : TRUE, FALSE

숫자 : 10L(Long), 10D(Double), 10F(Float)

ENUM : 패키지명까지 써주어야 한다

엔티티타입 : Type와 엔티티명을 활용한다(상속관계)

SELECT i FROM Item i WHERE TYPE(i) = Book

*case

COALESCE(expr1, expr2) : expr1, expr2부터 하나씩 검사해 NULL이 아니면 반환, 모두 NULL이면 NULL반환NULLIF(expr1, expr2) : expr1, expr2가 같으면 NULL, 아니면 expr1 반환

4. Affirmation (자기 선언)

- 나는, 무작정 공부시간을 투자하고 있지 않다. 나는, 복습과 인출로 기억을 잘 다져나가는 사람이다!

 

반응형

'회고' 카테고리의 다른 글

TIL_210616  (0) 2021.06.17
TIL_210615  (0) 2021.06.16
TIL_210525  (0) 2021.05.27
TIL_210524  (0) 2021.05.25
210521_TIL  (0) 2021.05.22