전체 글 194

BindingResult(FieldError, ObjectError), MessageCodesResolver를 통한 오류 코드 생성, Bean Validation

BindingResult BindingResult는 스프링이 제공하는 검증 오류를 보관하는 객체이다. 검증 오류가 발생하면 BindingResult 객체에 담아두면 된다. @PostMapping("/add") public String addItem(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) { // 필드 예외 if (!StringUtils.hasText(item.getItemName())) { bindingResult.addError(new FieldError("item", "itemName", "상품 이름은 필수입니다.")); } if (item.getPrice() == nul..

Backend/Spring 2024.01.11

JPQL의 소개와 기본 문법

JPQL JPQL은 Java Persistence Query Language의 약자로, JPA가 지원하는 객체지향 쿼리 언어이다. ORM을 사용하면 데이터베이스 테이블이 아닌 엔티티 객체를 대상으로 개발하므로 검색도 테이블이 아닌 엔티티 객체를 대상으로 하는 방법이 필요하다. JPQL은 이런 문제를 해결하기 위해 만들어졌다. JPQL의 특징은 다음과 같다. SQL이 데이터베이스 테이블을 대상으로 하는 데이터 중심의 쿼리라면, JPQL은 객체를 대상으로 하는 객체지향 쿼리이다. SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. JPQL은 결국 SQL로 변환된다. JPQL을 사용하면 JPA는 이 JPQL을 분석한 다음 적절한 SQL을 만들어 데이터베이스를 조회한다. 그리고 조회한 결과로 엔티티..

Backend/JPA 2024.01.10

HttpMessageConverter, ArgumentResolver, MappingJackson2HttpMessageConverter(JSON을 이용한 @RequestBody/@ResponseBody의 동작 원리)

@RequestBody는 클라이언트 측에서 보낸 HTTP 요청 메시지 바디의 데이터를 자바 객체로 변환해준다. 그리고 @ResponseBody는 객체 반환시 객체가 JSON 형태로 변환되어 응답이 나가도록 해준다. 이들의 동작 원리를 이해하기 위해서는 직렬화/역직렬화의 개념과 스프링 MVC에서 제공하는 HttpMessageConverter에 대해 알아야 한다. 직렬화/역직렬화 직렬화(Serialization)는 객체를 문자열 또는 바이트 스트림으로 변환하는 것을 의미한다. 반대로 역직렬화(Deserialization)는 문자열 또는 바이트 스트림을 다시 객체로 변환하는 것을 의미한다. 즉 @RequestBody는 클라이언트 측에서 보낸 HTTP 요청 메시지 바디의 데이터를 자바 객체로 변환하는 역직렬화..

Backend/Spring 2024.01.10

영속성 전이(cascade)와 고아 객체

영속성 전이(cascade) 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이 기능을 사용하면 된다. 예를 들어 엔티티를 저장하거나 삭제할 때 연관된 엔티티도 함께 저장하거나 삭제하는 경우이다. JPA는 cascade 옵션으로 영속성 전이를 제공한다. public enum CascadeType { ALL, // 모두 적용 PERSIST, // 양속 MERGE, // 병힙 REMOVE, // 삭제 REFRESH, // REFRESF DETACH // DETACH } cascade 옵션 적용 전 예를 들어 다음과 같이 부모와 자식이 일대다 관계로 정의되어 있다고 하자. @Entity public class Parent { @Id @GeneratedValue pr..

Backend/JPA 2024.01.09

프록시와 지연 로딩

프록시가 필요한 이유 다음 예제는 회원 엔티티를 찾아서 회원과 팀의 이름을 출력한다. Member member = em.find(Member.class, memberId); Team team = member.getTeam(); System.out.println("회원 이름: " + member.getName()); System.out.println("팀 이름: " + team.getName()); 반면 다음 예제는 회원 엔티티를 찾아서 회원의 이름만 출력하고, 회원과 관련된 팀 엔티티는 전혀 사용하지 않는다. Member member = em.find(Member.class, memberId); Team team = member.getTeam(); System.out.println("회원 이름: " + ..

Backend/JPA 2024.01.09

양방향 연관관계 매핑

객체와 테이블의 차이 객체의 양방향 연관관계: 정확히 말하자면 객체에는 양방향 연관관계가 없다. 서로 다른 단방향 연관관계 2개가 양방향처럼 보일 뿐이다. 회원 -> 팀 팀 -> 회원 테이블의 양방향 연관관계: 반면 데이터베이스 테이블은 외래 키 하나로 양쪽에서 서로 조인할 수 있다. 즉 외래 키 하나로 두 테이블은 양방향 연관관계를 맺는다. 회원 팀 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리한다. 따라서 엔티티를 단방향으로 매핑하면(단방향 연관관계), 참조를 하나만 사용하므로 이 참조로 외래 키를 관리하면 된다. 그런데 엔티티를 양방향으로 매핑하면(양방향 연관관계), '회원 -> 팀', '팀 -> 회원' 두 곳에서 서로를 참조한다. 즉 테이블의 외래 키는 하나인데, 객체에서 연관관계를 관리하..

Backend/JPA 2024.01.09

기본 키 매핑

JPA의 기본 키 매핑 JPA는 엔티티들을 영속성 컨텍스트에서 관리하는데, 영속성 컨텍스트에서 관리되려면 엔티티를 구분할 수 있는 식별자가 반드시 필요하다. 식별자가 되는 필드는 엔티티 클래스에서 @Id 어노테이션을 통해 지정할 수 있다. JPA가 제공하는 기본 키 생성 전략은 다음과 같다. 직접 할당: 기본 키를 애플리케이션에서 직접 할당한다. 자동 생성 IDENTITY: 기본 키 생성을 데이터베이스에 위임한다. SEQUENCE: 데이터베이스 시퀀스를 사용해서 기본 키를 할당한다. TABLE: 키 생성 테이블을 사용한다. 자동 생성 전략이 이렇게 다양한 이유는 데이터베이스 벤더마다 지원하는 방식이 다르기 때문이다. 예를 들어 오라클은 시퀀스를 제공하지만 MySQL은 시퀀스를 제공하지 않고 그 대신에 기..

Backend/JPA 2024.01.09

[백준] 11055. 가장 큰 증가하는 부분 수열

https://www.acmicpc.net/problem/11055 11055번: 가장 큰 증가하는 부분 수열 수열 A가 주어졌을 때, 그 수열의 증가하는 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가하는 www.acmicpc.net dp 문제이고 내가 실수한 코드는 다음과 같다. for (int i = 1; i = 0; j--) { if (input[j] < input[i]) { dp[i] = dp[j] + input[i]; break; } } } 그런데 만약 input 값이 "20 60 50 70"인 ..

CS/Algorism 2024.01.09

[백준] 5427. 불

https://www.acmicpc.net/problem/5427 5427번: 불 상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에 www.acmicpc.net bfs 문제로 크게 막힘없이 풀 수 있었다. 다만 주의할 점과 내가 놓친 부분은 다음과 같다. 상근이는 불이 붙으려는 칸으로 이동할 수 없다. 그리고 상근이가 있는 칸에 불이 옮겨옴과 동시에 상근이가 다른 칸으로 이동할 수 있다. 따라서 불이 먼저 이동하고, 상근이가 이동해야 한다. 불과 상근은 시간 당 한 칸씩 이동할 수 있다. 따라서 fireQue.size()만큼 각 불들이 한 칸씩 이동하도록 하고, pe..

CS/Algorism 2024.01.06

엔티티 매니저와 영속성 컨텍스트

엔티티 매니저 팩토리(entity manager factory), 엔티티 매니저(entity manager) 엔티티 매니저는 엔티티를 저장, 수정, 삭제, 조회하는 등 엔티티와 관련된 모든 일을 처리한다. 이름 그대로 엔티티를 관리하는 관리자이다. 엔티티 매니저 팩토리는 이름 그대로 엔티티 매니저를 만드는 공장인데, 엔티티 매니저 팩토리를 생성하는 비용은 매우 크다. 따라서 한 개만 생성해서 애플리케이션 전체에서 공유하도록 설계되어 있다. 반면, 공장에서 엔티티 매니저를 생성하는 비용은 거의 들지 않는다. 그리고 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드 간에 공유해도 되지만, 엔티티 매니저는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 절대..

Backend/JPA 2024.01.05