Spring

    Lombok 생성자 어노테이션

    롬복(Lombok) 롬복이란 어노테이션을 기반으로 코드를 자동완성 해주는 라이브러리를 말합니다. 그렇다면 롬복은 왜 사용할까요?? 롬복을 사용하면 getter/setter나 생성자 같이 반복되는 코드들을 줄여주기 때문에 코드의 가독성을 높일 수 있습니다. 그렇다면 이제 대표적인 롬복 어노테이션의 종류에 대해 알아보겠습니다. 어노테이션 종류 @Getter, @Setter 특정 필드 위에 해당 어노테이션을 붙여주면 자동으로 생성된 접근자와 설정자 메소드를 사용할 수 있습니다. 아래와 같이 클래스에 붙여줄 경우 모든 필드에 접근자와 설정자가 자동으로 생성됩니다. @Getter @Setter public class Member { private final Long id; private String name; p..

    뷰 컨트롤러

    모델 데이터나 사용자 입력을 처리하지 않는 간단한 컨트롤러의 경우, 뷰에 요청을 전달하는 일만 하는 컨트롤러를 선언할 수 있다. 뷰 컨트롤러는 WebMvcConfigurer 인터페이스를 구현해야 하며, WebMvcConfigurer는 스프링 MVC를 구성하는 메서드를 정의하고 있다. WebMvcConfigurer는 인터페이스임에도 불구하고, 정의된 모든 메서드의 기본적인 구현을 제공하므로, 필요한 메서드만 선택해서 오버라이딩하면 된다. @Configuration public class WebConfig implements WebMvcConfigurer { // 뷰 컨트롤러 @Override public void addViewControllers(ViewControllerRegistry registry) ..

    JPA와 컬렉션

    컬렉션 JPA는 자바에서 기본으로 제공하는 Collection, List, Set, Map 컬렉션을 지원한다. 컬렉션은 일대다나 다대다 엔티티 관계를 매핑하거나, @ElementCollection을 사용해서 값 타입을 하나 이상 보관할 때 사용된다. 래퍼 컬렉션 하이버네이트는 엔티티를 영속 상태로 만들 때 컬렉션 필드를 하이버네이트에서 준비한 컬렉션으로 감싸서 사용한다. 이는 컬렉션을 효율적으로 관리하기 위한 것으로, 원본 컬렉션을 감싸는 내장 컬렉션을 생성해서 이 내장 컬렉션을 사용하도록 참조를 변경한다. 컬렉션 래퍼 컬렉션 초기화 Collection, List PersistenceBag ArrayList Set PersistenceSet HashSet 하이버네이트의 이러한 특징 때문에 컬렉션을 사용할..

    프록시와 연관관계 관리

    프록시 지연로딩 기능을 사용하려면 실제 엔티티 객체 대신에 데이터베이스 조회를 지연시킬 수 있는 가짜 객체가 필요한데, 이 가짜 객체를 프록시라고 한다. 따라서 프록시를 사용하면 지연로딩을 통해 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다. em.getReference() em.find()로 엔티티를 조회하면 조회한 엔티티의 실제 사용여부와 상관없이 데이터베이스에서 조회하게 된다. 만약 엔티티를 실제 사용하는 시점까지 데이터베이스 조회를 미루고 싶은 경우 em.getReference()를 사용한다. em.getReference()를 호출하면 JPA는 실제 엔티티 객체를 생성하지 않는 대신, 데이터베이스 접근을 위임한 프록시 객체를 반..

    엔티티 매핑

    객체와 테이블 매핑 @Entity JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 필수로 붙여야 하며, @Entity가 붙은 클래스를 엔티티라고 한다. JPA는 엔티티 객체를 생성할 때 기본 생성자를 사용하기 때문에, 파라미터가 없는 public 또는 protected 생성자를 필수로 지정해주어야 한다. @Entity 어노테이션은 final, enum, interface, inner 클래스에는 사용할 수 없으며, 저장할 필드에도 final을 사용하면 안 된다. @Table @Table은 엔티티와 매핑할 테이블을 지정하며, 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다. @Table 어노테이션에 uniqueConstraint 속성을 지정하면 DDL 생성 시에 유니크 제약조건을..

    컨트롤러 요청과 응답

    HTTP 요청 헤더 조회 MultiValueMap은 하나의 키에 여러 값을 받을 수 있기 때문에 HTTP 헤더, HTTP 쿼리 파라미터와 같이 하나의 키에 여러 값을 받을 때 사용한다. @Slf4j @RestController public class RequestHeaderController { @RequestMapping("/headers") public String headers(HttpServletRequest request, HttpServletResponse response, HttpMethod httpMethod, Locale locale, @RequestHeader MultiValueMap headerMap, @RequestHeader("host") String host, @CookieVal..

    스프링에서의 영속성 관리

    트랜잭션 범위와 영속성 컨텍스트 스프링이나 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..