일상/일기장
TIL22.03.14 - Spring : Spring DAO, Spring MVC
jmaster
2022. 3. 14. 23:35
Spring DAO
dataSource→connection → dao
- ojdbc
- JDBC 기능을 제공하기 위한 Oracle Driver 라이브러리
- commons-dbcp
- Apache 그룹에서 제공하는 Data Source 라이브러리
- JDBC
- SpringDAO 기능을 제공하는 라이브러리 - DataSource 관련 기능
- spring-tx 라이브러리도 의존관계에 의해 빌드 처리 : 트렌젝션 관리 기능을 제공하는 라이브러리
- Apache 그룹에서 제공하는 commons-dbcp2 라이브러리의 BasicDataSource 클래스를 Spring Bean으로 등록
- Connection 객체 생성 관련 정보를 필드에 전달하여 저장 - Setter Injection
ApplicationContext context=new ClassPathXmlApplicationContext("08_dao.xml");
System.out.println("===============================================================");
DataSource apacheDataSoutce=context.getBean("apacheDataSource",DataSource.class);
Connection apacheConnection=apacheDataSoutce.getConnection();
System.out.println("apacheConnection = "+apacheConnection);
apacheConnection.close();
System.out.println("===============================================================");
DataSource springDataSource=context.getBean("springDataSource",DataSource.class);
Connection springConnection=springDataSource.getConnection();
System.out.println("springConnection = "+springConnection);
springConnection.close();
System.out.println("===============================================================");
((ClassPathXmlApplicationContext)context).close();
- SpringDAO 기능을 이용하여 DAO 클래스 작성 - spring-jdbc 라이브러리 빌드 처리
- JdbcTemplate 클래스의 템플릿 메소드를 호출하여 DAO 클래스 작성
- JdbcTemplate 객체를 제공받아 사용하는 방법(2가지 방법 중 하나를 선택)
- JdbcTemplate 객체를 Spring Container에게 제공받아 필드에 저장 - DI(권장)
- JdbcDaoSupport 클래스를 상속받아 JdbcTemplate 객체를 저장한 필드 사용
- Bean Configuration File에서 StudentDAOImpl 클래스를 Spring Bean으로 등록할 때 JdbcTemplate
- 클래스의 Spring Bean을 필드에 저장하여 의존관계 설정 - DI(Dependency Injection)
public class StudentDAOImpl implements StudentDAO {
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
- JdbcTemplate.update(String sql, Object... object) : SQL 명령(INSERT,UPDATE,DELETE)를DBMS 서버에 전달하여 실행하는 메소드 - 조작행의 갯수 반환
- 매개변수에 SQL 명령과 InParameter(?)에 저장될 값을 차례대로 나열하여 메소드 호출
@Override
public int insertStudent(Student student) {
String sql="insert into student values(?,?,?,?,?)";
return jdbcTemplate.update(sql, student.getNo(), student.getName()
, student.getPhone(), student.getAddress(), student.getBirthday());
}
- JdbcTemplate.queryForObject(String sql,RowMapper<T> rowMapper,Object... args)
- SQL 명령(SELECT)을 DBMS 서버에 전달하여 실행하는 메소드
- 단일행의 검색결과를 하나의 객체(값)로 반환할 경우 사용되는 메소드
- SQL 명령, RowMapper 객체, InParameter 전달값을 매개변수에 차례대로 나열하여 전
- RowMapper : 검색결과를 Java 객체로 매핑하여 반환하기 위한 객체
- 제네릭은 검색행을 Java 객체로 표현하기 위한 자료형(클래스) 설정
- mapRow 메소드를 오버라이드 선언하여 매핑정보 제공
- EmptyResultDataAccessException : queryForObject() 메소드에 의해 전달된 SQL 명령의 검색결과가 존재하지 않는 경우 발생되는 예외
@Override
public Student selectStudent(int no) {
try {
String sql="select * from student where no=?";
return jdbcTemplate.queryForObject(sql, new RowMapper<Student>() {
@Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student=new Student();
student.setNo(rs.getInt("no"));
student.setName(rs.getString("name"));
student.setPhone(rs.getString("phone"));
student.setAddress(rs.getString("address"));
student.setBirthday(rs.getString("birthday"));
return student;
}
}, no);
return jdbcTemplate.queryForObject(sql, new StudentRowMapper(), no);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
- JdbcTemplate.query(String sql,RowMapper<T> rowMapper,Object... args)
- SQL 명령(SELECT)을 DBMS 서버에 전달하여 실행하는 메소드
- 다중행의 검색결과를 List 객체로 반환할 경우 사용되는 메소드
- SQL 명령, RowMapper 객체, InParameter 전달값을 매개변수에 차례대로 나열하여 전달
@Override
public List<Student> selectStudentList() {
String sql="select * from student order by no";
return jdbcTemplate.query(sql, new StudentRowMapper());
}
- RowMapper 인터페이스를 상속받은 자식클래스(내부클래스) - 매핑기능을 제공하는 클래스
- 익명의 내부클래스 대신 사용할 클래스 - 재사용성
public class StudentRowMapper implements RowMapper<Student> {
@Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student=new Student();
student.setNo(rs.getInt("no"));
student.setName(rs.getString("name"));
student.setPhone(rs.getString("phone"));
student.setAddress(rs.getString("address"));
student.setBirthday(rs.getString("birthday"));
return student;
}
}
}
Spring MVC
web.xml
- web.xml : WAS 실행시 프로젝트 자원을 컨텍스트로 제공하기 위한 정보를 설정한 파일
- ⇒ 리스너 설정, 필터 설정, 서블릿 설정, 에러 페이지 설정 등
- context-param : 컨텍스트로 존재하는 모든 클래스에 값을 제공하기 위한 엘리먼트
- 모든 웹프로그램(Front Controller)에서 사용하는 공통적인 Spring Bean을 등록하기 위해 Bean Configuration File
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
- listener : WAS 실행시 Listener 클래스를 객체로 생성하기 위한 엘리먼트
- Listener 클래스 : ServletContextListener 인터페이스를 상속받은 자식클래스
- contextInitialized() 메소드 : Listener 객체 생성 후 자동으로 호출되는 메소드 - 초기화 작업
- contextDestroyed() 메소드 : Listener 객체 소멸 전 자동으로 호출되는 메소드 - 마무리 작업
- listener-class : Listener 클래스를 설정하기 위한 엘리먼트
- ContextLoaderListener : WebApplicationContext 객체(Spring Container)를 생성하고 bean Configuration File을 읽어 Spring Bean으로 등록된 모든 클래스를 객체로 생성하여 컨텍스트로 존재하는 모든 클래스에서 사용할 수 있도록 제공하는 Listener 클래스
- ⇒context-param 엘리먼트의 contextConfigLocation 이름으로 제공되는 값이 Bean Configuration
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- servlet : 서블릿 클래스를 웹프로그램(서블릿)으로 등록하는 엘리먼트⇒ servlet 엘리먼트를 사용하여 Front Controller 기능을 제공하는 웹프로그램을 여러개 등록 가능
- DispatcherServlet : 클라이언트의 모든 요청을 처리학 위한 Sprign Framework에서 제공하는 Front Controller 클래스
- 클라이언트의 요청을 처리하기 위해 WebApplicationContext 객체로 Bean Configuration File 을 읽어 서블릿에서 사용될 Spring Bean 으로 등록된 모든 클래스를 객체로 생성하여 서블릿(DispatcherServlet)에서 사용되도록 제공
- init-param 엘리먼트의 contextConfigLocation 이름으로 제공되는 값이 Bean Configuration
- init-param : Servlet클래스에서 필요한 값을 제공하기 위한 엘리먼트⇒Bean Configuration Fille을 엔터 또는 , 또는 ; 으로 구분하여 설정
- ⇒Annotation 기반의 Bean Configuration File은 하나만 등록 가능 ,
- ⇒ 서블릿이 사용할 Bean Configuration File 을 여러개 등록 가능
- load-on-startup: WAS 실행시 서블릿 클래스를 객체로 생성하기 위한 엘리먼트
- ⇒ 클라이언트의 요청 없이 WAS 실행시 미리 서블릿 클래스를 객체로 생성하기 위해 사용
- ⇒ 엘리먼트의 값은 0보다 큰 정수값을 사용하며 값이 작을 수록 먼저 객체로 생성
<servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet>
- DispatcherServlet : 클라이언트의 모든 요청을 처리학 위한 Sprign Framework에서 제공하는 Front Controller 클래스
- ⇒ DispatcherServlet 클래스(Front Controller)를 웹프로그램으로 등록
- servelt-mapping : 웹프로그램(서블릿) 실행을 위해 요청할 URL 주소를 설정하는 엘리먼트
- 클라이언트의 모든(/) 요청에 대해 서블릿이 실행되도록 설정
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
controller
- Command Controller : 클라이언트의 요청을 처리하기 위한 클래스 - Model
- ⇒Spring Framework에서 제공하는 Controller 인터페이스를 상속받아 작성
- handleRequest : 클라이언트의 요청을 처리하기 위한 명령을 작성하는 메소드
- ⇒ Front Controller(DispatcherServlet)에 의해 자동 호출되는 메소드
- ⇒ HttpServletRequest 객체와 HttpServletResponse 객체를 매개변수로 제공받아 요청 처리
- ⇒ 뷰 관련 정보를 Spring Framework에서 제공하는 ModelAndView 클래스의 객체를 저장하여 반환
- ModelAndView : 응답 관련 정보를 저장하기 위한 클래스
- ⇒ 요청에 대한 처리 결과와 뷰페이지 관련 정보를 저장하여 Front Controller(DispatcherServlet)
public class ListContoller implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//클라이언트 요청에 대한 처리를 위해 Service 클래스의 메소드를 호출하여 처리결과를 반환받아 저장
List<Member> memberList=new ArrayList<Member>();
memberList.add(new Member("aaa", "홍길동"));
memberList.add(new Member("bbb", "임꺽정"));
memberList.add(new Member("ccc", "전우치"));
- ModelAndView 객체 생성 - 요청 처리 메소드의 반환값
ModelAndView modelAndView=new ModelAndView();
- ModelAndView.addObject(String attributeName, Object attributeValue)
- ModelAndView 객체에 요청에 대한 처리 결과를 저장하기 위한 메소드
- HttpServletRequest.setAttribute() 메소드와 유사한 기능 제공 - Request Scope
- 뷰페이지(JSP)에서 EL과 JSTL를 사용하여 응답 처리
- ModelAndView.setViewName(String viewName) : 뷰페이지 관련 정보(ViewName)을 변경하는 메소드
modelAndView.addObject("memberList", memberList);
modelAndView.setViewName("member_list");
return modelAndView;
Spring Bean
- Command Controller 클래스를 Spring Bean으로 등록
<beans:bean class="xyz.itwill09.mvc.ListController" id="listController"/>
<beans:bean class="xyz.itwill09.mvc.ViewController" id="viewController"/>
- Spring Famework에서 제공하는 SimpleUrlHandlerMapping 클래스를 Spring Bean으로 등록
- SimpleUrlHandlerMapping : Front Controller(DispatcherServlet)에게 클라이언트 요청을 처리하기 위한 Command Controller 클래스의 Spring Bean의 beanName을 제공하기 위한 클래스⇒ 클라이언트의 요청정보(key:String)와 Command Controller 클래스의 Spring BeanName(Value:String)을 Map 객체의
- ⇒ mappings 필드에 Map 객체를 생성하여 인젝션 처리
<beans:bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<beans:property name="mappings">
<beans:props>
<beans:prop key="/list.do">listController</beans:prop>
<beans:prop key="/view.do">viewController</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
- InternalResourceViewResolver : 뷰이름(ViewName)을 전달받아 뷰페이지(JSP)로 변환하여 제공하는 클래스
- InternalResourceViewResolver : 뷰이름(ViewName)을 전달받아 응답할 뷰페이지(JSP)로 변환하여 제공하는 클래스
- ⇒ prefix 필드에는 뷰이름 앞부분에 추가될 값을 인젝션 처리
- ⇒ suffix 필드에는 뷰이름 뒷부분에 추가될 값을 인젝션 처리