[스프링과 스프링 MVC] 4. LocalDate 바인딩이 왜 자주 깨지는가
·
Web/Web Basics
Formatter로 “문자열 → 타입” 변환 규칙을 등록한다스프링 MVC의 파라미터 바인딩은 편하다.요청 파라미터가 문자열로 들어와도int/boolean 같은 기본 타입은 자동 변환해주고DTO 필드에도 알아서 채워준다그런데 실전에서 가장 자주 터지는 타입이 있다.날짜(LocalDate, LocalDateTime) 1) 왜 날짜에서 에러가 자주 나나HTTP 요청 파라미터는 기본적으로 전부 문자열이다.예를 들어 사용자가 폼에서 날짜를 입력하면 이런 문자열이 온다.dueDate=2020-10-10문제는 스프링이 이 문자열을LocalDate 객체로 바꾸는 규칙을 “항상 자동으로 알 수는 없다”는 점이다.즉 바인딩 과정에서“String을 LocalDate로 변환할 수 없다”같은 타입 변환 에러가 발생할 수 있다...
[스프링과 스프링 MVC] 3. 파라미터 바인딩과 Model
·
Web/Web Basics
스프링 MVC는 request를 직접 만지지 않아도 된다서블릿 MVC에서는 요청 데이터를 읽는 방식이 명확했다.request.getParameter("title")request.setAttribute("todos", list)즉 request를 직접 만지는 코드가 컨트롤러에 반복된다.스프링 MVC는 이 부분을 크게 추상화했다.요청 파라미터를 자동으로 모아서 객체(DTO)에 넣어준다View로 넘길 데이터도 Model로 넣으면 알아서 request에 옮겨준다그래서 컨트롤러 코드가 짧아지고 의도가 더 분명해진다. 1) 파라미터 바인딩: DTO를 파라미터로 받으면 자동으로 채워준다스프링 MVC는 컨트롤러 메서드 파라미터를 보고요청 파라미터를 자동으로 수집해서 넣어준다.예를 들어 요청이 이렇게 들어온다고 하자.t..
[스프링과 스프링 MVC] 2. 스프링 MVC는 “프론트 컨트롤러”로 움직인다
·
Web/Web Basics
서블릿 MVC에서는 보통 이런 흐름이었다.URL마다 서블릿이 매핑된다서블릿이 doGet/doPost에서 요청을 처리한다필요하면 JSP로 forward/redirect 한다스프링 MVC는 이 흐름을 더 강하게 “통제”한다.스프링 MVC에서는 모든 요청이 반드시 DispatcherServlet을 거친다 DispatcherServlet은 스프링 MVC의 프론트 컨트롤러(Front-Controller)이다.즉 “모든 요청의 입구”이다. // ================================// [Controller 예시] @GetMapping / @PostMapping// - 서블릿의 doGet/doPost 대신 "메서드 단위"로 매핑한다// ================================@..
[스프링과 스프링 MVC] 1. DI와 빈(Bean)
·
Web/Web Basics
이전까지는 이런 구조로 왔다.Controller(서블릿)가 요청을 받고Service/DAO를 호출하고JSP로 forward/redirect로 흐름을 제어한다문제는 규모가 커질수록 코드가 이렇게 변한다는 점이다.컨트롤러가 서비스 객체를 직접 new로 만들기 시작한다서비스가 DAO를 직접 new로 만들기 시작한다구현체가 바뀌면 여기저기 코드가 같이 바뀐다테스트가 어려워진다(가짜 객체로 바꾸기 힘들다)이 문제를 해결하려면 “객체를 누가 만들고, 누가 누구를 참조하게 만들지”를 분리해야 한다.이때 등장하는 핵심 개념이 DI(의존성 주입)이다. // ================================// [DI가 없을 때] Controller가 Service를 직접 new 해서 결합이 강해진다// - 구현..
[상태 유지와 공통 처리] 5. MyBatis 설정 흐름
·
Web/Web Basics
DataSource → SqlSessionFactory → Mapper ScanMyBatis를 “코드 사용” 관점에서 보면 Mapper 인터페이스만 만들면 되는 것처럼 보인다.하지만 그게 동작하려면 컨테이너(스프링) 쪽에서 연결을 해줘야 한다.핵심 연결은 딱 3단계이다.DataSource 준비 (HikariCP)SqlSessionFactory 준비Mapper Scan 등록 // ================================// [JDBC DAO에서 반복되는 코드] 자원 얻기/닫기 + ResultSet 매핑// - MyBatis가 주로 줄여주는 부분이 여기다// ================================public class TodoJdbcDao { private fina..
[상태 유지와 공통 처리] 4. MyBatis는 무엇을 해결하는가
·
Web/Web Basics
JDBC에서 반복되는 “매핑/자원관리”를 줄인다JDBC로 DAO를 작성할 수는 있다.그리고 실제로 기본기는 JDBC로 충분히 잡는 게 맞다.하지만 JDBC DAO를 계속 작성해보면특정 패턴의 코드가 계속 반복되는 걸 느끼게 된다.Connection 얻기PreparedStatement 만들기파라미터 setXXX 바인딩executeQuery/executeUpdate 호출ResultSet에서 꺼내서 VO로 매핑자원 close 처리이 중에서 특히 반복이 큰 부분이 두 가지다.ResultSet → 객체 매핑자원 정리/예외 처리 패턴MyBatis는 이 반복을 줄이기 위해 등장한 SQL 매핑 프레임워크이다. MyBatis는 “SQL 매핑 프레임워크”이다MyBatis를 한 문장으로 말하면 이렇다.SQL 실행 결과를 ..
[상태 유지와 공통 처리] 3. Connection Pool / DataSource / HikariCP
·
Web/Web Basics
연결을 미리 만들어두고 빌려 쓴다JDBC는 DB와 연결해야 SQL을 실행할 수 있다.그래서 Connection이 필요하다.그런데 문제가 있다.Connection 생성은 생각보다 비용이 큰 작업이다 요청이 들어올 때마다 매번 새 연결을 만들면느려지고DB 연결 수가 급격히 늘고결국 서버가 버티기 힘들어진다그래서 실무에서는 거의 무조건 Connection Pool을 쓴다. Connection을 새로 만드는 게 왜 비싼가Connection을 만든다는 건 단순히 객체 하나 만드는 게 아니다.DB와 네트워크(TCP) 연결을 맺는다인증/권한 확인 같은 협상이 들어간다네트워크 왕복이 발생한다즉, 요청마다 이 과정을 반복하면 성능이 크게 떨어진다. Connection Pool의 아이디어는 단순하다해결책은 미리 만들어..
[상태 유지와 공통 처리] 2. JDBC란?
·
Web/Web Basics
자바가 DB와 통신하는 표준 방식DB 연동을 한다는 말은 결국 이 뜻이다.자바 프로그램이 네트워크로 DB 서버에 연결한다SQL을 전송한다DB가 실행한 결과를 다시 받아서 처리한다이 흐름을 자바 표준 API로 정리한 게 JDBC이다.즉 JDBC는 “DB 연결과 SQL 실행을 위한 자바 표준 규격”이다. JDBC로 DB 작업을 할 때 항상 나오는 3가지 객체JDBC는 결국 아래 세 가지 객체를 중심으로 돌아간다.ConnectionPreparedStatementResultSet이 세 개만 이해하면 JDBC의 큰 흐름은 끝난다. // ================================// [JDBC 기본 흐름] (조회: SELECT)// 1) Connection 얻기// 2) PreparedStatem..