전체 글 681

[JPA] 페치 조인 ( JOIN FETCH )

엔티티의 연관 엔티티를 로드하는 전략은 두 가지가 있다. 1. 지연로딩 ( Lazy ) 2. 즉시로딩 ( Eager ) 그러나 두 가지 전략은 문제가 있다. 즉시로딩은 연관된 엔티티를 로드하려고 SELECT문이 자동으로 하나 생성되어 실행된다. 지연로딩은 연관된 엔티티에 무언가가 접근하면 SELECT문이 자동으로 생성되어 실행된다. 이를 N+1문제라 한다. 개발자는 한 개의 쿼리를 만들었는데, 자동으로 N개의 쿼리가 생성되어 실행되는 것이다. 이처럼 N개의 쿼리문이 추가로 실행된다면 반복적으로 DB와 I/O가 발생하여 성능에 좋지 못한 영향을 준다. JOIN FETCH 페치 조인의 목적은 하나의 쿼리로 연관된 엔티티를 모두 로드하는 것이다. 이는 특정 로직에 필요한 '데이터'를 추출하려는 목적이 아니다...

Dev/JPA 2023.06.15

[JPA] 묵시적 조인보다는 명시적 조인

JPA는 JPA Parser가 JPQL을 파싱하면서 연관된 엔티티를 참조하는 경우, JOIN이 없어도 JOIN절을 생성하는 묵시적 조인을 지원한다. Member 엔티티는 Team 엔티티와 연관된다. JPQL에서는 연관된 엔티티를 '.'으로 접근할 수 있다. String jpql1 = "SELECT distinct m.team FROM Member m "; TypedQuery typedQuery1 = entityManager.createQuery(jpql1,Team.class); List results1 = typedQuery1.getResultList(); JPQL은 JOIN문은 없고 '.'으로 연관 엔티티에 접근하였다. 그럼 정말 JPA(하이버네이트)가 자동으로 JOIN문을 만드는지 확인해보자. INN..

Dev/JPA 2023.06.15

[CodingTest] BOJ1260 DFS와BFS ( DFS,BFS ) With 파이썬

https://www.acmicpc.net/problem/1260 1260번: DFS와 BFS 첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사 www.acmicpc.net ◎ 문제풀이 DFS, BFS 문제이다. DFS는 STACK, BFS는 QUEUE를 사용하면 된다. 재귀호출은 함수가 STACK 영역에 쌓이므로 재귀호출로 구현한다. 주의점 1) BFS에서 노드 방문이력은 큐에 들어가기 직전에 변경해야한다. 2) 양방향 관계임을 주의하자. 3) 인접노드 탐색시 오름차순 순으로 탐색해야 하므로 정렬이 필요하다. ◎ 코드 from ..

문제풀이 2023.06.15

[CodingTest] BOJ3085 사탕게임 ( BruteForce ) With 파이썬

https://www.acmicpc.net/problem/3085 3085번: 사탕 게임 예제 3의 경우 4번 행의 Y와 C를 바꾸면 사탕 네 개를 먹을 수 있다. www.acmicpc.net ◎ 문제풀이 NXN 크기의 사탕상자를 교환하여 같은 색상이 연속된 사탕개수의 최댓값을 탐색하는 문제이다. 시간제한이 1초인데 N의 최댓값이 50이니 반복문으로 완전탐색해도 시간제한에 걸리지 않는다. 1) 사탕상자에서 연속된 같은 색상 사탕개수의 최댓값을 구하는 함수를 만든다. 2) 인접한 사탕을 교환할 때마다 1)에서 생성한 함수를 호출한다. 브루트포스는 원리는 단순하나 단순한만큼 코드가 길어지므로 구현력을 키워야 한다. ◎ 코드 import sys input = sys.stdin.readline n = int(i..

문제풀이 2023.06.15

[JPA] 쿼리결과 변환하기 ( JPQL 함수 )

SELECT [ 컬럼 ] FROM [ 테이블 ] WHERE [ 조건 ] SELECT문은 FROM의 레코드집합에서 WHERE로 필터링 된 레코드 중 원하는 컬럼을 출력하는 쿼리문이다. 출력되는 컬럼은 조건에 따라 다른 값으로 변환될 수 있다. CASE 조건식 CASE 조건식은 JPQL에서도 사용가능하다. SELECT CASE WHEN m.age = 60 THEN '경로요금' ELSE '일반요금' END FROM Member m WHERE m.city IN ( SELECT c FROM City c WHERE c.name = '대구' ) 대구에 거주하는 회원의 나이를 출력하는 SELECT문인데, CASE 조건식으로 출력결과가 변환되었다. 나이가 10살 이하면 학생요금 나이가 60살 이상이면 경로요금 그 사이면..

Dev/JPA 2023.06.14

[JPA] 서브쿼리 ( SubQuery )

SELECT [ 컬럼 ] FROM [ 테이블 ] WHERE [ 조건문 ] SELECT문은 FROM 레코드집합에서 WHERE 조건으로 필터링 된 레코드 중 원하는 컬럼을 출력한다. 만약 다른 테이블의 데이터가 필요하면 JOIN 연산을 사용한다. JOIN연산으로 다른 테이블의 데이터에 접근 가능하다. 말그대로 '데이터'에 접근이 가능하다. 예를들어, 학생 테이블을 조회하는데 수학성적이 필요하면 수학테이블에 접근하여 학생의 수학점수(데이터)를 가져 올 수 있다. JPQL 코드 SELECT s, m FROM Student s JOIN s.math m ON s.student_id = m.student_id 그런데 만약 '데이터'가 아니라 '정보'가 필요하다면 어떻게 할까? 데이터가 아니라 가공된 정보가 필요할 수..

Dev/JPA 2023.06.14

[JPA] JOIN 과 JOIN FETCH의 차이

JOIN과 JOIN FETCH를 헷갈릴 수 있다. FROM 엔티티A JOIN FETCH 엔티티B FROM 엔티티A JOIN 엔티티B JOIN FETCH를 사용하면 엔티티A,엔티티B 둘 다 영속화 된다. JOIN을 사용하면 엔티티A만 영속화 된다. JOIN은 엔티티B를 굳이 영속화 할 이유는 없는데 엔티티B의 테이블에 있는 데이터가 필요한 경우 사용된다. 예를들어, 학생(Student)을 수학성적(Math)순으로 정렬한 데이터를 가져오고 싶다. 필요한 엔티티는 학생(Student) 엔티티이다. 수학(Math) 엔티티는 필요 없으나 ORDER BY로 정렬하려면 Math 테이블의 score 필드가 필요하다. 이런 경우에 일반 JOIN을 사용한다. SELECT s FROM Student s JOIN s.math..

Dev/JPA 2023.06.14

[CodingTest] BOJ1991 트리순회 ( tree ) With 파이썬

1991번: 트리 순회 첫째 줄에는 이진 트리의 노드의 개수 N(1 ≤ N ≤ 26)이 주어진다. 둘째 줄부터 N개의 줄에 걸쳐 각 노드와 그의 왼쪽 자식 노드, 오른쪽 자식 노드가 주어진다. 노드의 이름은 A부터 차례대로 알파 www.acmicpc.net ◎ 문제풀이 순회를 하려면 '노드'를 '기억'해야 한다. '기억'을 담당하는 자료구조는 STACK이다. 나는 두 가지를 놓쳐서 이 문제를 어렵게 풀었다. 1) 파이썬의 딕셔너리 자료형을 몰랐다. tree = {} 딕셔너리 자료형은 Map처럼 key-value 구조로 이루어져 있다. 딕셔너리 자료형을 몰라서 인덱스로 접근하는 리스트 자료형을 사용하였다. 2) 재귀호출을 발상하지 못했다. 재귀호출은 함수의 호출을 이용한다. 함수는 STACK영역에 쌓이므로..

문제풀이 2023.06.14

[CodingTest] BOJ9095 1,2,3 더하기 ( DP ) With 파이썬

9095번: 1, 2, 3 더하기 각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다. www.acmicpc.net ◎ 문제풀이 1,2,3 기저조건이 있고 목표값까지 가는 경우의 수를 구하는 문제이니 DP문제이다. 1,2,3으로 10을 구하는 경우의 수를 d(10)이라고 하자. 10을 구하는 사건은 3가지 사건이 있다. 사건 ① : 9 + 1 사건 ② : 8 + 2 사건 ③ : 7 + 3 3가지 사건은 모두 독립사건이다. 그러므로 d(10) = d(9) + d(8) + d(7)이 성립된다. dp는 기저조건으로 독립사건을 구하여 점화식을 도출하는 것이 중요하다. ◎ 코드 n = int(input()) def dp(value) : d = [0]*11 d[1],d[2],d[3] ..

문제풀이 2023.06.14

[JPA] 페이징 API

MySQL, ORACLE의 페이징 처리는 복잡하기로 유명하다. JPA는 API 2개만 알면 페이징 구현이 가능하다. 그리고 JPA가 알아서 DB에 맞추어 복잡한 페이징 SQL을 자동 생성한다. 페이징 쿼리 1) String jpql = "select m from Member m order by m.name desc"; List resultList = entityManager.createQuery(jpql, Member.class) .setFirstResult(10) .setMaxResults(20) .getResultList(); 페이징 쿼리 2) String jpql = "SELECT e FROM Employee e ORDER BY e.id"; TypedQuery query = entityManager..

Dev/JPA 2023.06.13