Spring

Spring(3)_DB연결(2)&MVC

clumsy0g 2019. 12. 12. 16:49

DB연결을 완료했으니, 다음은 MVC 구조를 구현할 차례다.

먼저, Model

웹 요청 ---> Controller ( --> DAO --> SqlMapper ) --> View

의 과정으로 진행되므로, 위의 것들이 필요함을 알수 있다.

또한, mvc와 관련된 설정은 servlet-context.xml에서 할 수 있다.

servlet-context.xml은 웹의 요청을 전반적으로 어떻게 처리할 것인지의 구조(request-processing infrastructure)를 그려놓는 것.

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="com.yjjo.app" />

</beans:beans>

annotation (@)을 사용하겠다고 설정

view를 return할때 가할 설정들 (prefix, suffix)

@Controller, @Repository 등의 component들을 자동으로 읽어올 package를 설정


웹사이트의 Main 화면을 만들어 보도록 하자.
base-package 하위에 Controller, dao, bean 들을 저장할 패키지들을 생성해야한다.

*항상 서버가 스타트 될때는 Console에서 오류가 없는지 살펴보자.. *

MainController.java

package com.yjjo.app.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MainController {

    @RequestMapping({"/","/main"})
    public String main() {

        return "main";
    }

}

요청 url이 여러개일 경우 {}로 표시

method등 다른 인자값을 줄경우는 value=""로 명시

( 책의 Chapter07. 스프링 MVC : 기본기 - 04. 컨트롤러 구현 - 4.2 참고 )

main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>한국무형문화재 춤 전자문화지도</title>
</head>
<body>
<ul>
<li><a href="${pageContext.request.contextPath}/mapSearch">지도 춤 검색</a></li>
<li>텍스트 춤 검색</li>
<li>미디어</li>
<li>연구소개</li>
</ul>

</body>
</html>

${pageContext.request.contextPath} 을 이용하여 현재 Context root를 고정지정하였다.

이로써 유지보수가 좀 더 간편해진다. (Context root 확인은 프로젝트 우클릭 - properties - Web Project Settings )

이제 mapSearch 경로 에 해당하는 페이지를 만들어보자.


Mapper에 정의된 SQL문을 시행하기 위해서는 SqlSession(Template) 이 필요하다.

sqlSession은 sqlSessionFactory와 의존관계에 있으며, 설정하는 방법은 2가지가 있다. (참고 : https://mybatis.org/spring/ko/sqlsession.html )

Dao는 @Repository 로 생성할수도 있고 root-context.xml에 bean으로 등록하여 scope를 singgleton으로 설정 수도 있다.

기본적으로, Spring은 모든 객체를 싱글톤 패턴으로 제공하기 때문에 상관은 없는듯 하다.

(참고 : http://blog.devenjoy.com/?p=360)

Dao <--- sqlSession <--- sqlSessionFactory의 의존관계를 가지고 있다.

  1. sqlSession, sqlSessionFactory bean 생성

root-context.xml

    <!-- MyBatis-Spring -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation"    value="classpath:mybatis-config.xml" />
        <property name="dataSource" ref="dataSource" />
    </bean>
<!--     <property name="mapperLocations"    value="classpath:/mappers/*.xml" /> -->

    <bean id="sqlSession" name="sqlSession"
        class="org.mybatis.spring.SqlSessionTemplate"
        destroy-method="clearCache">
        <constructor-arg name="sqlSessionFactory"
            ref="sqlSessionFactory" />
    </bean>
  1. DAO 작성
package com.yjjo.app.dao;

import java.util.List;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import com.yjjo.app.bean.BoardBean;

@Repository
public class BoardDao {

    @Inject
    private SqlSession sqlSession;

    public List<BoardBean> selectBoardTable(String high, String mid, String low) {

        return sqlSession.selectList(statement, high, mid, low);
    }

}

여기서 statement 는 DB에 질의할 쿼리문를 의미한다.

Mapper파일에 쿼리문을 작성한뒤 id를 지정하고, 이를 statement에 String으로 명시해주면 된다.

  1. Mapper파일에 쿼리문 작성

src/main/resrouces의 mapper폴더에 xml 파일을 생성.

BoardMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.yjjo.app.BoardMapper">

<select id="selectAll" resultType="com.yjjo.app.bean.BoardBean">

select "KTD_ID", "KTD_NAME"
from public."TN_KTD_MASTER"

</select>



</mapper>

namespace는 되도록 저런 식으로 경로를 넣어주는 편이 좋다.

그 이유는 인터페이스를 이용하여 다른방법으로 sql문을 구축할 수 있기 때문이다.

또한 resultType에는 자바파일의 위치까지 명시해줘야하는데.

이것이 싫다면 resultType="BoardBean"이라고 간략히 쓰고 싶다면 아래와 같이 설정해주면 된다.

mybatis-config.xml

<typeAliases>
        <typeAlias type="com.yjjo.app.bean.BoardBean" alias="BoardBean" />
</typeAliases>

BoardDao.java

package com.yjjo.app.dao;

import java.util.List;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import com.yjjo.app.bean.BoardBean;

@Repository
public class BoardDao {

    @Inject
    private SqlSession sqlSession;

    public List<BoardBean> selectBoardTable(String high, String mid, String low) {

        return sqlSession.selectList("com.yjjo.app.BoardMapper"+".selectAll");
    }
}

아까의 statement를 namespace.id 의 형식으로 바꿔준다. 필요하다면 뒤의 인자에 받은 파라미터를 줄수도 있다. (파라미터는 1개만 줄수 있는듯 하다. 위와 같이 여러개면 Map이나 List와 같은 자료구조로 묶어주어야할 듯하다.)

마지막으로, mapper를 자동으로 찾을수 있도록 mapper의 위치를 설정파일에 명시해준다.

root-context.xml

    <!-- MyBatis-Spring -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation"    value="classpath:mybatis-config.xml" />
        <property name="mapperLocations"    value="classpath:/mappers/*.xml" /> 
        <property name="dataSource" ref="dataSource" />
    </bean>
  1. dao로부터 전달받은 데이터를 View에 전달

Controller

View에 전달하기 위해서 Model 객체를 이용한다.

package com.yjjo.app.controller;

import java.util.List;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.yjjo.app.bean.BoardBean;
import com.yjjo.app.dao.BoardDao;

@Controller
@RequestMapping("/mapSearch")
public class MapSearchController {
    @Inject
    BoardDao dao;

    @RequestMapping(value={"","/categorical"}, method=RequestMethod.GET)
    public String categoricalGet() {



        return "categorical";
    }

    @RequestMapping(value="/categorical", method=RequestMethod.POST)
    public String categoricalPost(String high, String mid, String low, Model model) {

        System.out.println(high+mid+low);

        List<BoardBean> boardList = null;

        boardList = dao.selectBoardTable(high, mid, low);

        model.addAttribute("boardList", boardList);

        return "categorical";
    }

}

addAtrribute( view에 전달할 이름, 전달할 객체)

  1. View 에서 사용

categorical.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>지도 춤 검색</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/mapSearch/categorical" method="post">
대분류
<select name="high">
<option value=null >전체선택</option>
</select><br>
중분류
<select name="mid">
<option value=null >전체선택</option>
</select><br>
소분류
<select name="low">
<option value=null >전체선택</option>
</select><br>
<button type="submit">검색</button>
</form>

<ul>
<c:forEach items="${boardList}" var="board">
<li>${board.ktd_name}</li>
</c:forEach>
</ul>


</body>
</html>