전체 글

전체 글

    스프링에서의 영속성 관리

    트랜잭션 범위와 영속성 컨텍스트 스프링이나 J2EE 컨테이너 환경에서 JPA를 사용하면 컨테이너가 제공하는 전략을 따라야 한다. 스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다. 트랜잭션을 시작할 때 영속성 컨텍스트를 생성하고 트랜잭션이 끝날 때 영속성 컨텍스트를 종료한다. 같은 트랜잭션 안에서는 항상 같은 영속성 컨텍스트에 접근한다. 스프링 트랜잭션 AOP @Transactional 어노테이션을 선언하면 호출한 메서드를 실행하기 직전에 스프링 트랜잭션 AOP가 동작한다. 스프링 트랜잭션 AOP는 대상 메서드를 호출하기 직전에 트랜잭션을 시작하고, 대상 메서드가 정상 종료되면 트랜잭션을 커밋하면서 종료된다. 이때 트랜잭션을 커밋하면 JPA는 먼저 영속성 컨텍스트를 플러시해서 변..

    영속성 컨텍스트와 연속성 관리

    엔티티 매니저 JPA가 제공하는 기능은 크게 엔티티와 테이블을 매핑하는 설계 부분과 매핑한 엔티티를 실제 사용하는 부분으로 나눌 수 있다. 엔티티 매니저는 엔티티를 저장, 수정, 삭제, 조회하는 등 엔티티와 관련된 모든 일을 처리한다. 엔티티 매니저 팩토리 엔티티 매니저 팩토리는 엔티티 매니저를 만드는 공장으로, 만드는 비용이 크기 때문에 데이터베이스 당 한 개만 만들어서 애플리케이션 전체에서 공유한다. 이후 필요할 때마다 엔티티 매니저 팩토리에서 엔티티 매니저를 생성해서 사용한다. 하이버네이트를 포함한 JPA 구현체들은 엔티티 매니저 팩토리를 생성할 때 커넥션 풀도 생성한다. 엔티티 매니저는 데이터베이스 연결이 꼭 필요한 시점(트랜잭션을 시작할 때)까지 커넥션을 얻지 않다가, 트랜잭션을 시작할 때 커넥..

    N+1 문제와 해결 방법

    즉시 로딩 회원 @Entity public class Member { @Id @GeneratedValue private Long id; @OneToMany(mappedBy = "member", fetch = FetchType.EAGER) private List orders = new ArrayList(); ... } 주문정보 @Entity @Table(name = "ORDERS") public class Order { @Id @GeneratedValue private Long id; @ManyToOne private Member member; ... } 예를 들어 회원과 주문정보가 1:N 양방향 연관관계이고, 회원이 참조하는 주문정보인 Member.orders를 즉시 로딩하는 경우 특정 회원 하나를 em..

    다이나믹 프로그래밍 (DP)

    다이나믹 프로그래밍 전체 문제를 작은 문제로 나누어 해결한 결과를 저장해뒀다가 나중에 큰 문제의 결과와 합하여 풀이하는 알고리즘 문제의 최적 해결 방법이 부분 문제의 최적 해결 방법으로 구성되는 문제, 즉 최적 부분 구조를 가지는 문제에 대해 적용 가능하다. DP 가정 큰 문제를 작은 문제로 나눌 수 있다. 작은 문제에서 구한 답은 그것을 포함하는 큰 문제에서도 동일하다. DP, 그리디, 분할정복 참고로 그리디는 항상 그 순간에 최적이라고 생각되는 것을 선택하면서 풀이해 나가는 것이고, 다이나믹 프로그래밍은 중복된 하위 문제들의 결과를 저장해뒀다가 풀어나간다는 차이점이 있다. 또한 분할 정복으로 분류되는 병합 정렬과 퀵 정렬은 중복된 하위 문제들을 푸는 것이 아니기 때문에 다이나믹 프로그래밍으로 분류하지..

    투 포인터와 슬라이딩 윈도우

    투 포인터 시작점과 끝점 또는 왼쪽 포인터와 오른쪽 포인터 두 지점을 기준으로 하는 문제풀이 전략 일반적으로 배열이 정렬되어 있을 때 유용하며, 2개의 포인터가 좌우로 자유롭게 움직이면서 문제를 풀이한다. 대표적인 문제로 배열의 구간합과 관련된 문제나 수열의 연속합과 같은 문제에서 사용한다. 예제 배열에서 구간합이 m 이상인 구간의 최소 길이 찾기 n, m = map(int, input().split()) a = list(map(int, input().split())) left, right = 0, 0 ans = n + 1 sum = a[0] while left = m: ans = min(ans, right - left + 1) sum -= a[left] left += 1 if left > right a..

    서블릿, JSP, MVC 패턴

    서블릿 서블릿은 자바로 웹 페이지를 동적으로 생성하는 서버 프로그램으로, 자바 코드 안에 HTML을 포함한다. 서블릿을 사용하면 동적으로 원하는 HTML을 만들 수 있으나, 자바 코드에 HTML을 만들어야 하므로 매우 복잡하고 비효율적 @WebServlet(name = "memberFormServlet", urlPatterns = "/servlet/members/new-form") public class MemberFormServlet extends HttpServlet { private MemberRepository memberRepository = MemberRepository.getInstance(); @Override protected void service(HttpServletRequest re..

    빈 생명주기와 콜백

    빈 생명주기 스프링 빈은 객체를 생성하고 의존관계 주입이 다 끝나야지만 필요한 데이터를 사용할 수 있는 준비가 완료되기 때문에, 초기화 작업은 의존관계 주입이 모두 완료되고 난 다음에 호출된다. 따라서 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려주고, 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 보낸다. 객체의 생성과 초기화 생성자는 파라미터로 필수정보를 받고 메모리를 할당해서 객체를 생성하는 책임을 가지는 반면에, 초기화는 생성된 값들을 활용해서 외부 커넥션을 연결하는 등 무거운 동작을 수행한다. 따라서 생성자 안에서 초기화 작업을 하는 것보다 객체를 생성하는 부분과 초기화하는 부분을 명확하게 나누는 것이 유지보수 관점에서 좋다. 하지만 초기화 작업이 내부..

    의존관계 주입 방법

    Setter 주입 필드의 값을 변경하는 Setter 메서드를 통해서 의존관계를 주입받는 방법 선택, 변경 가능성이 있는 의존관계에 사용 @Component public class OrderService { private MemberRepository memberRepository; @Autowired public void setMemberRepository(MemberRepository memberRepository) { this.memberRepository = memberRepository; } } 필드 주입 필드에 바로 주입하는 방법으로, 외부에서 변경이 불가능하기 때문에 사용하지 않는 것이 좋다. 애플리케이션의 실제 코드와 관계없는 테스트 코드나 스프링 설정을 목적으로 하는 @Configurati..

    그래프 관련 알고리즘

    위상정렬 그래프 이론에서 사용하는 정렬 방식으로 주로 사이클이 없는 방향 그래프에서, 정점들을 방향을 거스르는 간선없이 나열한다. 여러 작업들이 주어질 때 그 중 특정 작업을 마치기 위해 선행되어야 하는 작업들을 모두 정렬하는 테크닉 from collections import deque v, e = map(int, input().split()) # 모든 노드에 대한 진입 차수는 0으로 초기화 indegree = [0] * (v + 1) graph = [[] for _ in range(v + 1)] for _ in range(e): a, b = map(int, input().split()) graph[a].append(b) # 진입차수를 1 증가 indegree[b] += 1 # 알고리즘 수행 결과를 담을..