Category: Develop

0

JPA 연관 관계 - 고아 객체

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 고아 객체란? 부모 엔티티와 연관관계가 끊어진 자식 엔티티 고아 객체 제거 부모 엔티티와 연관관계 가 끊어진 자식 엔티티를 자동으로 제거 @OneToOne, @OneToMany 만 가능하다. orphanRemoval = true @Entity@Getter@Setterpublic class Parent { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) private List<Child> childList = new ArrayList<>(); public void addChild(Child child){ childList.add(child); child.setParent(this); }} public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { Child child1 = new Child(); Child child2 = new Child(); Parent parent = new Parent(); parent.addChild(child1); parent.addChild(child2); em.persist(parent); em.flush(); em.clear(); Parent savedParent = em.find(Parent.class, parent.getId()); savedParent.getChildList().remove(0); transaction.commit(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); }} Parent 에서 Child를 삭제할 때 delete 쿼리가 발생하게 된다.

0

JPA 연관 관계 - 즉시로딩과 지연로딩

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 N + 1 문제 하나의 쿼리(1) 를 날린 후 조회된 결과 값과 연관된 데이터 를 가져오기 위해 결과의 행수(N) 만큼 추가 쿼리가 발생하는 문제 즉시로딩 FetchType.EAGER 로 설정하게 되면 즉시 조회하게 된다. Join 해서 한방 쿼리로 가져오는 방법 데이터를 가져온 후 후속 쿼리를 날리는 기법, 해당 방법은 N + 1 문제를 일으킨다. @ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "TEAM_ID")private Team team; 프록시와 즉시로딩 주의 즉시 로딩을 적용하면 예상하지 못한 SQL 이 발생 즉시 로딩은 JPQL 에서 N + 1 문제를 일으킨다. JPA 가 만들어주는 쿼리는 내부적으로 최적화가 이뤄진다. JPQL 은 내부적으로 SQL 로 번역된 후 데이터를 가져온 다음에 연관 데이터에 대해 후속적으로 쿼리가 발생한다. 해결법 1 : fetch join 해결법 2 : @EntityGraph 해결법 3 : batch size @ManyToOne, @OneToOne 은 기본이 즉시 로딩 LAZY 로 설정한다. @OneToMany, @ManyToMany 는 기본이 지연 로딩 지연로딩

0

JPA 연관 관계 - 프록시 객체

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 프록시 객체의 특징 실제 클래스를 상속 받아서 만들어진다. 실제 클래스와 겉 모양이 같다. 사용자 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다. 프록시 객체는 실제 객체의 참조를 보관한다. 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다. 프록시 객체는 처음 사용할 때 한번만 초기화 프록시 객체를 초기화 할때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다. 초기화 되면 프록시 객체를 통해 실제 엔티티에 접근이 가능하다. 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입 체크시 주의해야 한다. (== 비교 실패, 대신 instance of 사용) 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference() 를 호추랳도 실제 엔티티를 반환한다. 영속성 컨텍스트의 도움을 받을 수 없는 준 영속 상태일때, 프록시를 초기화 하면 문제 발생 org.hibernate.LazyInitializationException 예외를 터트린다. em.find() vs em.getReference() em.find() 데이터 베이스를 통해 실제 엔티티 객체를 조회한다. em.getReference() 데이터 베이스 조회를 미루는 가짜(프록시) 엔티티 객체 를 조회한다. public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { Member member = new Member(); member.setUsername("hello"); em.persist(member); em.flush(); em.clear(); Member savedMember = em.find(Member.class, 1L); printMemberAndTeam(savedMember); transaction.commit(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); } private static void printMember(Member member){ System.out.println("member = " + member.getUsername()); } private static void printMemberAndTeam(Member member) { String username = member.getUsername(); System.out.println("username = " + username); Team team = member.getTeam(); System.out.println("team = " + team.getName()); }}

0

JPA 연관 관계 - 일대다

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 공통 Mapping 정보를 관리하기 위한 MappedSuperclass Entity 에 공통적으로 들어가는 Mapping 정보를 관리해 코드가 중복해서 작성하는 것을 방지하기 위해 사용하는 어노테이션 상속관계 Mapping 이 아니다. 부모 클래스를 상속 받는 자식 클래스에 Mapping 정보만 을 제공한다. 직접 생성해서 사용할 일이 없으므로 추상클래스(abstract) 를 사용하는 것이 좋다. MappedSuperclass 클래스를 상속 받기 위해서는 같은 @MappedSuperclass 를 사용한 클래스나 @Entity 을 이용한 클래스만 상속이 가능하다. 요구 사항 모든 Entity 에는 생성자, 생성일, 수정자, 수정일 정보가 들어가야 한다. 모든 Entity 에 공통적으로 들어가는 Mapping 정보 를 관리하기 위한 BaseEntity 클래스를 생성한다. @MappedSuperclasspublic abstract class BaseEntity { private String createdBy; private LocalDateTime createdDate; private String lastModifiedBy; private LocalDateTime lastModifiedDate;} 공통 Mapping 정보는 상속 을 통해 현재 Entity 에 적용할 수 있다.

0

JPA 연관 관계 - 다대일

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 다 대 일연관관계 매핑시 고려사항 다중성 단방향, 양방향 연관관계 주인 테이블 외래키 하나로 양쪽 조인 가능 사실 방향이라는 개념이 없음 객체 참조용 필드가 있는 쪽으로만 참조 가능 한쪽만 참조하면 단방향 양쪽이 서로 참조하면 양방향 연관관계 주인

0

JPA JPQL - Fetch Join

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 N+1 문제란 ? 데이터 조회를 위해 한번의 쿼리가 발생하지만 연관관계에 의해 연관된 객체 모두를 가져오기 위해 N 번의 쿼리가 발생하는 문제 필요한 데이터 조회를 위해 한번의 Select 쿼리가 발생해 객체를 가져왔지만, 연관관계가 설정된 객체는 Lazy 설정 으로 인해 실제 값이 아닌 Proxy 객체 로 대체하는데 해당 객체에 접근할 경우 실제 데이터를 가져오기 위해 처음에 조회된 데이터 만큼 쿼리가 추가적으로 발생하는 문제 Fetch Join Lazy 설정을 무시하고 연관된 객체를 한번에 가져온다. JPQL 에서는 N + 1 문제를 해결하기 위해 fetch join 을 제공한다. fetch join 을 이용해 JPQL 을 작성하게 되면 Lazy 설정을 무시하고, Order 조회시 Member 객체와 Delivery 객체를 전부 다 가져온다. public List<Order> findAllWithMemberDelivery(){ return em.createQuery( "select o from Order o"+ " join fetch o.member m" + " join fetch o.delivery d", Order.class ).getResultList();}

0

JPA JPQL (Java Persistence Query Language)

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 JPQL JPQL 은 객체지향 쿼리 언어 로 테이블 을 대상으로 쿼리하는 것이 아니라 엔티티 객체 를 대상으로 쿼리한다.JPQL 은 SQL 을 추상화 해서 특정 데이터 베이스 SQL 에 의존하지 않는다. JPQL 문법 select m from Memeber as m where m.age > 18 Entity 와 속성 은 대소문자 구분 O (Member, age) JPQL 키워드 는 대소문자 구분 X (select, from, where) 엔티티 이름 사용, 테이블 이름이 아님 별칭(alias) 은 필수 (m) TypeQuery, Query 반환 타입 형태에 따라 사용하는 타입이 다르다.

0

JPA JPQL - Projection (Select)

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 Projection 대상 Entity, 임베디드 타입, 스칼라 타입(숫자, 문자등 기본 타입) // Entity select m from Member m// Entity select m.team from Member m// 임베디드 타입select m.address from Member m// 스칼라 타입select m.username, m.age from Member m

0

JPA - 객체지향 쿼리 언어

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 객체 지향 쿼리 언어 종류 JPQL JPA Criteria QueryDSL 네이티브 SQL JDBC API 직접 사용, MyBatis, SrpignjdbcTemplate 함께 사용 JPQL JPA 를 사용하면 엔티티 객체 를 중심으로 개발 문제는 검색 쿼리 검색을 할때도 테이블이 나닌 엔티티 객체 를 대상으로 검색 모든 DB 데이터를 객체로 변화해서 검색하는 것은 불가능 애플리케이션이 필요한 데이터만 DB 에서 불러오려면 결국 검색 조건인 포함된 SQL 이 필요 JPA 는 SQL 을 추상화한 JPQL 이라는 객체지향 쿼리 언어 제공 SQL 과 문법 유사, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원 JPQL 은 엔티티 객체를 대상으로 쿼리 SQL 은 데이터 베이스 테이블을 대상으로 쿼리 public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { String qlString = "select m from Member m where m.username like '%kim%'"; List<Member> result = em.createQuery(qlString, Member.class) .getResultList(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); }}

0

프로그래머스 - 양과 늑대 Cpp

문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/92343 프로그래머스 - 양과 늑대 Cpp 문제 풀이이 문제의 가장 어려운 점은 한번 방문한 노드를 여러번 방문할 수 있다는 것이다. 중복을 허용한 탐색을 진행하면 탐색이 끝나지 않으므로, 최대한 중복 방문을 제거하기 위해 비트마스크 를 이용해 방문한 노드들을 관리하면서 같은 상태에서 같은 노드 방문을 못하게 하는게 이 문제의 핵심이다.그 다음으로 어려웠던 부분은 이 탐색의 끝은 항상 루트 노드에서 끝나야 한다는 점이고, 반대로 생각하면 루트 노드에서 탐색 가능한 범위만 정답이 될 수 있는 것이다. 처음에 이 부분을 염두하지 않아서 계속 틀렸다. 이 두 부분만 잘 염두 하면 이 문제를 해결하는데 큰 어려움은 없다. 전체 소스 코드#include <iostream>#include <string>#include <vector>using namespace std;int maxValue = 0;void dfs(int sheep, int woof, int start, int state, vector<int> info, vector<vector<int>>& grape, vector<vector<bool>>& check) { if (woof >= sheep) { return; } maxValue = max(maxValue, sheep); for (int i = 0; i < info.size(); i++) { int node = 1 << i; int isVisited = state & node; int nextState = state | node; if (grape[start][i] == 0) { continue; } if (check[nextState][i] == true) { continue; } check[nextState][i] = true; if (isVisited) { dfs(sheep, woof, i, nextState, info, grape, check); } else { if (info[i] == 0) { dfs(sheep + 1, woof, i, nextState, info, grape, check); } else { dfs(sheep, woof + 1, i, nextState, info, grape, check); } } check[nextState][i] = false; }}int solution(vector<int> info, vector<vector<int>> edges) { int answer = 0; vector<vector<int>> grape = vector<vector<int>>(info.size() + 1, vector<int>(info.size() + 1, 0)); vector<vector<bool>> check = vector<vector<bool>>((1 << 18) - 1, vector<bool>(17 + 1, false)); for (vector<int> edge : edges) { int from, to; from = edge[0]; to = edge[1]; grape[from][to] = 1; grape[to][from] = 1; } maxValue = 0; int state = 1 << 0; check[state][0] = true; dfs(1, 0, 0, state, info, grape, check); answer = max(maxValue, answer); return answer;}

0

Oracle 12c - Docker 로 시작하기

목차 Oracle - Docker 로 시작하기 Oracle 12c - Docker 로 시작하기 11g 제한사항Oracle 11g 의 경우 11G 제한이 걸려 있어서 부득이 하게 12c 로 변경 했다. 11g 가 11G 까지라서 11g 인건가….. SQL Error [12953] [72000]: ORA-12953: The request exceeds the maximum allowed database size of 11 GB 이미지 다운로드 Image : absolutapps/oracle-12c-ee docker pull absolutapps/oracle-12c-ee 이미지 실행하기

0

Oracle - Docker 로 시작하기

목차 Oracle - Docker 로 시작하기 Oracle 12c - Docker 로 시작하기 이미지 다운로드Oracle 의 경우 Mac 버전 데이터 베이스를 지원하지 않기 때문에 Docker 를 이용해 Oracle 를 이용해보려고 한다. Image : jaspeen/oracle-xe-11g docker pull jaspeen/oracle-xe-11g 이미지 실행하기docker run --name oracle11g -d -p 1521:1521 jaspeen/oracle-xe-11g# Docker Volumn 과 외부 Volumn 연결docker run --name oracle11g -d -p 1521:1521 -v ~/docker/oracle:/u01/app/oracle jaspeen/oracle-xe-11g Sqlplus 실행

0

프로그래머스 - 양궁 대회 (Python)

https://programmers.co.kr/learn/courses/30/lessons/92342 프로그래머스 - 키패드누르기 Cpp 프로그래머스 - 키패드누르기 Python 유의 사항 화살을 맞춘 개수를 저장하고 정렬하는데 있어서 주의해야 한다. 정렬에 대한 가중치가 앞자리가 아닌 뒷자리 에 있으므로 값을 저장할 때 뒤집어서 저장한 후 내림 차순으로 정렬해 가장 큰 값을 가져와 해당 값을 뒤집으면 가장 낮은 점수를 많이 맞춘 순서대로 정렬된 값을 가져올 수 있다. cases = []maxDiff: int = 0results = []def getScore(index: int): return 10 - indexdef calScores(ryan: list, apeech: list) -> None: diff: int = 0 apeech_score: int = 0 ryan_score: int = 0 global maxDiff for i in range(11): if apeech[i] == 0 and ryan[i] == 0: continue if ryan[i] > apeech[i]: ryan_score += getScore(i) else: apeech_score += getScore(i) diff = ryan_score - apeech_score if diff <= 0: return if diff >= maxDiff: oneCase: str = ''.join(list(map(str, ryan[::-1]))) if(diff > maxDiff): results.clear() maxDiff = diff results.append(oneCase)def makeAllCase(start: int, choice: int, n: int, ryan: list) -> None: if(choice >= n): cases.append(ryan.copy()) return for i in range(start, 11): ryan[i] += 1 makeAllCase(i, choice+1, n, ryan) ryan[i] -= 1def solution(n, info): answer = [] ryan = [0] * 11 makeAllCase(0, 0, n, ryan) for case in cases: calScores(case, info) if len(results) > 0: results.sort(reverse=True) answer = list(map(int, results[0][::-1])) # print(answer) else: answer.append(-1) return answer

0

백준 1197 - 최소 스패닝 트리 (Cpp)

링크 https://www.acmicpc.net/problem/1197 전체 소스 코드#include <algorithm>#include <iostream>#include <string>#include <vector>#define endl '\n';using namespace std;int find(int node, vector<int>& v) { if (node == v[node]) { return node; } return v[node] = find(v[node], v);}void merge(int a, int b, vector<int>& v) { if (a != b) { v[a] = b; }}int main(void) { int vertex, edge; int totalWeight = 0; cin >> vertex >> edge; vector<pair<int, pair<int, int>>> edges = vector<pair<int, pair<int, int>>>(vertex + 1); vector<int> v = vector<int>(vertex + 1); for (int i = 0; i < v.size(); i++) { v[i] = i; } for (int i = 0; i < edge; i++) { int from, to, weight; cin >> from >> to >> weight; edges.push_back({weight, {from, to}}); } sort(edges.begin(), edges.end()); for (auto we : edges) { int weight = we.first; pair<int, int> e = we.second; int from = e.first; int to = e.second; int setA = find(from, v); int setB = find(to, v); if (setA != setB) { totalWeight += weight; merge(setA, setB, v); } } cout << totalWeight << endl; return 0;}

0

Oracle - Clustering Factor

Oracle - Clustering Factor 데이터베이스에서는 특정 컬럼을 기준으로 같은 값을 갖는 데이터가 서로 모여있는 정도를 의미한다. 인덱스 클러스터링 팩터가 좋다. 고 하면 인덱스 정렬 순서 와 테이블 정렬 순서 가 서로 비슷하다는 것을 말한다. Index Scan의 Cost에 큰 영향을 준다. Index Lookup을 통해 Data를 읽는 일량을 결정한다.