2025-08-05
1일 1아티클
데보션
JPA와 QueryDSL의 한계를 jOOQ로 극복
문제 상황
- Kotlin의 data class와 JPA의 궁합 문제
- data class : 불변성, copy method, 구조 분해, etc.
- JPA : 불변성이 고려 대상 아니므로 data class 사용 불가
→ 엔티티와 비슷한 불변 DTO 클래스 추가 작성
→ DTO가 중구난방으로 계속 추가되는 문제 발생
- QueryDSL의 한계
- 데이터의 양 증가 → 쿼리 성능 문제 → SQL 재작성/튜닝 필요성
→ QueryDSL의 지원 기능 한계 → Native Query 사용하면서 QueryDSL 장점 포기 - 현재 QueryDSL은 유지보수 되지 않는 상태
- 데이터의 양 증가 → 쿼리 성능 문제 → SQL 재작성/튜닝 필요성
해결 방법
- JPA, QueryDSL → JDBC, jOOQ
- jOOQ
- QueryDSL과 동일하게, 타입에 안전한 코드 작성 가능 & Native SQL 100% 호환
- annotation processor 기반의 QueryDSL과 달리, SQL DSL 코드 생성 기반으로 더 안정적/직관적
- jOOQ
- 빌링 시스템 적용 순서
-
- 검색/조회
- 복잡한 조회 중심의 QueryDSL 코드 → jOOQ 전환
- 일정 기간동안 성능 개선 여부, 유지보수 용이성 검증
- 검색/조회
-
- JPA로 구현한 CRUD
- 변경이 적은 엔티티부터 JPA → JDBC 전환
- 도메인 모델 → 불변 객체
- JPA로 구현한 CRUD
-
- 쿼리 실행 결과 프로젝션 방식
- aggregation 클래스 도입
- jOOQ, JDBC로 가져온 엔티티를 조합해 응답 객체 구성
- 이 과정에서 불필요해진 DTO 클래스 전부 제거
- 쿼리 실행 결과 프로젝션 방식
-
효과
- 복잡한 쿼리의 표현력 향상
- 순수 SQL 수준에서 자유롭게 쿼리 작성 가능
- 코드 레벨에서 서브쿼리, 윈도우 함수 등 구현 가능
- 성능 최적화 용이
- Lazy 로딩, N+1 문제, 원치 않는 join 발생 감소
- SQL 튜닝을 통한 응답 시간 개선
- 불변 객체 중심의 설계
- Kotlin의 장점을 살려 불변 모델로 작성 → 도메인 안정화
- Aggregation 클래스로 응답 구조 분리
- 불필요한 클래스 파일(dto) 제거 → 다이어트 효과
- 빌드, 운영 환경 안정화
- QueryDSL의 annotation processor 이슈, 버전 충돌 이슈 등 제거
- 기술 스택 업그레이드 및 개발 생산성 향상
다른 의견
- OpenFeign 팀에서 fork하여 업데이트중인 QueryDSL 사용
- Spring에서 공식적으로 지원 결정
- JDSL(라인에서 제작한 오픈소스) 도입
- Entity만 Java로 만들고 Kotlin과 혼용
QueryDSL은 JPQL의 대체, JOOQ는 SQL의 대체임을 기억하자.
JOOQ가 QueryDSL의 대체가 되는 것은 아님.
오늘 배운 것
-
CSS
구성
- 선택자 : 정의한 스타일을 적용할 대상
- 선언부 : 선택자에 적용할 스타일
{}
/* 주석 문법 */
적용 방법
- 인라인 스타일 : 태그 안에
style=""
- 내부 스타일 :
<head> 내부의 <style> 이 안에 작성 </style> </head>
- 외부 스타일 시트 : .css 파일로 관리,
<link>
로 연결, 모든 파일에서 재사용 가능
cascading
- 중요도 (3단계 origin) : user agent < user < author
- 명시도 (선택자) : X > Y > Z
- 로드
- 기본 선택자
- ID 선택자(#) - X
- 클래스 선택자(.) - Y
- 태그 선택자 - Z
- 전체 선택자(*) - user agent의 css reset 용도
- 복합 선택자
- 자식 선택자(>)
- 자손 선택자()
- 인접 형제 선택자(+)
- 일반 형제 선택자(-)
가상 클래스 선택자
E:nth-child(n)
: 앞에서 n번째 자식 요소tr:nth-child(2n) {color: red;}
style 적용 순서
p → .text(class) → #unique(id)
요소 크기 계산 방식 지정
box-sizing
- 값
- content-box(콘텐츠 영역만 포함, default) (row*column)
- border-box(padding과 border 포함) (row x column - pad_r x pad_c)
내일 할 일
- 정처기 필기 모의고사 CBT 풀어보고 오답노트 (con.)