1. NamedParameterJdbcTemplate 란?
- jdbcTemplate와 동일한 기능을 제공
- 차이점은 인덱스 기반의 파라미터가 아니라 이름 기반의 파라미터를 설정
?, ? 대신 :이름, :이름을 사용

- 쿼리에 ?가 많은 경우에는 NamedParameterJdbcTemplate을 사용하도록 권장한다.
2. NamedParameterJdbcTemplate 예제
1) dispatcher-servlet.xml에 NamedParameterJdbcTemplate 등록
NamedParameterJdbcTemplate는 setter 메서드가 없기 때문에 생성자로 dataSource를 주입시켜주어야 함

2) DAO 클래스들의 인터페이스 선언
MeberDAO.java 복사 붙여넣기해서 NLMemberDao.java 생성
NoticeDAO.java 복사 붙여넣기해서 NLNoticeDao.java 생성
기존의 MeberDAO와 NoticeDAO는 interface로 변경 후 NL의 클래스들은 해당 인터페이스를 구현
DAO의 컨트롤러 메서드 수정
[MemberDAO 인터페이스와 NoticeDAO 인터페이스]


3) DAO(컨트롤러)의 컨트롤러 메서드 수정
[NLMemberDao.java]
> JdbcTemplate를 사용하는 것이 아니기 때문에 NamedParameterJdbcTemplate로 수정하여 의존 주입
> MapSqlParameterSource를 사용하면 key, value 한 쌍으로 저장되기 때문에 파라미터를 키 값으로 저장할 수 있음
> MapSqlParameterSource의 addValue("파라미터이름", 파라미터값) 메서드를 사용 -> 쿼리 문에서 :파라미터이름을 주고 해당 파라미터 이름을 키 값으로, 파라미터 값을 매개변수로 줌

> 회원가입 메서드를 MapSqlParameterSource를 사용하면 아래와 같이 설정
(insert 메서드가 두번 구현되어있어서 빨간색 줄이 보임)

> SqlParameterSource를 사용하면 자동으로 커맨드 객체의 getter를 사용하여 파라미터를 설정

[NLNoticeDao.java]

> Map<String, Object>을 사용하여 설정할 수 있음
Map이기 때문에 put으로 키(파라미터이름) 값과 밸류(파라미터값) 값을 설정




3. 스프링 컨테이너의 추가 설명(부모-자식 계층)
먼저, 스프링 컨테이너는 days01 언급했지만 다시 한 번 설명하자면 스프링 빈 객체를 생성하고 조립하는 일명 공장이라고 생각하면 된다. dispatcher-servlet.xml 설정 파일을 보고 스프링 빈 객체를 생성하고 조립을 한다.
web.xml에서 아래와 같은 설정으로 front controller를 생성하였다.

관리를 목적으로 front controller를 여러 개 등록할 수 있다.
ex)
??? 요청만 받는 - 스프링 MV[C] : fornt controller 등록 -> 이 front controller의 서블릿이름-servlet.xml 따로 있음
ajax 요청만 받는 - 스프링 MV[C] : fornt controller 등록 -> 이 front controller의 서블릿이름-servlet.xml 따로 있음
관리자 요청만 받는 - 스프링 MV[C] : fornt controller 등록 -> 이 front controller의 서블릿이름-servlet.xml 따로 있음
각 컨테이너는 스프링 빈 객체를 공유할 수 없다.
DispatcherServlet은 그 자체가 서블릿이기 때문에 한 개 이상의 DispatcherServlet 설정하는 것은 가능하나 (여러 개 선언 가능) DispatcherServlet 따로 만들면 각각 별도의 WebApplicationContext 생성이 되기 때문에 빈 객체는 공유할 수 없다.
공통 빈을 필요로 하는 경우 ContextLoaderListener 사용하여 공통으로 사용될 빈을 설정할 수 있다.
ContextLoaderListener를 ServletLisener로 등록하고 contextConfigLocation 컨텍스트 파라미터를 이용하여 공통으로 사용될 빈 정보를 담고 있는 설정 파일 목록을 지정한다.
ContextLoaderListener 생성하는 WebApplicationContext는 루트 컨텍스트를 부모로 사용하는 자식 컨텍스트가 된다.
이제 예제를 통해서 어떻게 부모와 자식 계층의 컨테이너로 설정하는지 확인해보자!
4. WebApplicationContext 계층(부모-자식 계층의 컨테이너) 예제
front controller는 1개
dispatcher-servlet.xml => 선언된 빈 객체들 중에 DB 연동할 때 사용하는 스프링 빈은 부모 컨테이너(Application Context)에서 생성하도록 코딩
> 기존의 dispatcher-servlet.xml을 복사하여 dispatcher-service.xml로 이름을 변경하여 2개의 xml 파일을 준비
[dispatcher-servlet.xml]

[dispatcher-service.xml]

xml 파일을 위와 같이 수정하고 실행을 하면 당연히 예외가 발생한다.
톰캣이 실행할 때 web.xml 설정으로 인해서 서블릿 객체가 생성(WebApplicationContext 공장 : 서블릿명-servlet.xml을 찾음)
dispatcher-servlet.xml은 올라가지만 dispatcher-service.xml은 올라가지 않기 때문이다.
이 부분에 대한 설정을 해주어야 예외가 발생하지 않는다.
이제 web.xml에 가서 부모 컨테이너를 만들어서 자식 컨테이너에서 사용할 수 있도록 설정해주자
<context-param> 태그 안에 <param-name>과 <param-value> 태그로 공통으로 사용될 빈 정보를 담고 있는 설정 파일 목록을 지정해주고
<listener> 태그 안에 <listener-class> 태그로 ContextLoaderListener를 ServletListener로 등록해준다.

번외) 다른 예시로 살펴보기

> 생성되는 WebApplicationContext 간의 관계

ContextLoaderListener가 생성하는 WebApplicationContext는 웹 어플리케이션에서 루트 컨텍스트가 되며, DispatcherServlet이 생성하는 WebApplicationContext는 루트 컨텍스트를 부모로 사용하는 자식 컨텍스트가 된다. 이때 자식은 root가 제공하는 빈을 사용할 수 있기 때문에 각각의 DispatcherServlet이 공통으로 필요로 하는 빈을 ContextLoaderListener를 이용하여 설정하는 것이다.
'TIL > Spring' 카테고리의 다른 글
[SIST] Spring_days07_스프링 트랜잭션 전파방식(propagation) (0) | 2022.07.19 |
---|---|
[SIST] Spring_days06_Spring 트랜잭션 처리 (0) | 2022.07.18 |
[SIST] Spring_days05_Spring의 DB 연동(Spring JDBC) / JdbcTemplate (0) | 2022.07.17 |
[SIST] Spring_days05_Spring 파일 업로드 (0) | 2022.07.16 |
[SIST] Srping_days04_Spring MVC (0) | 2022.07.14 |