일상/일기장

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 클래스(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 필드에는 뷰이름 뒷부분에 추가될 값을 인젝션 처리