프로그래밍/Spring

[Spring] DB연결, Controller에 대해 알아보자

byungmin 2020. 8. 20. 19:29

스프링 흐름도

웹브라우저가 요청해서 응답을 받을 때까지 흐름도

1. 요청 -> DispatcherServlet이 FrontController역할을 한다. 

root-context.xml에 있는 빈들을 메모리에 올린다.

 

2. XXXController로 연결해서 주소창에 매핑되어 있는 이름에 맞는 SubController로 이동한다.

 

3. Controller에서 DB에서 가져올 데이터가 필요하면 XXXDAO를 통해 DB와 연동 후 데이터를 가져온다.

 

4. Controller는 Model이름을 DispatcherServlet에 반환한다.

 

5. ViewResolver는 Model의 이름 앞 뒤에 접두사, 접미사를 붙여서 /WEB-INF/view/뷰이름.jsp로 만든다.

(ViewResolver는 servlet-context.xml에서 빈으로 등록되어 있다.)

 

6. /WEB-INF/view/뷰이름.jsp 에 해당하는 경로를 찾아서jsp를 불러오고 웹브라우저에 응답해준다.


DB연결과 Controller를 생성해서 memo관련 jsp를 연결해서 보여주자.

1. DB연결 셋팅

MyBatis 이용

 

root-context.xml에 셋팅해준다.

(1) DriverManagerDataSource 빈 등록

<!-- [1] DataSource 빈을 등록 
	(1) DriverManagerDataSource 빈을 등록 (server.xml에 등록 안되어있으면)
	(2) server.xml에 설정되어 있는 DBCP를 JNDI로 찾아쓰도록 등록하는 방법
-->

<!-- (1) DriverManagerDataSource --> 
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
	<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" />
	<property name="username" value="scott"/>
	<property name="password" value="tiger"/>
</bean>

 

(2) MyBatis 빈 등록

<!-- MyBatis 등록 -->
<!-- [2] SqlSessionFactoryBean 등록 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/> <!-- DriverManagerDataSource id를 넣어줌-->
	<property name="configLocation" value="classpath:spring/config/mybatis-config.xml"/>
	<!-- classpath: 하면 resources 경로 잡아줌 -->
</bean>

<property name="dataSource" >

- dataSource의 참조유형을 위에 만들었던 DriverManagerDataSource의 아이디로 넣어준다.

<property name="configLocation">

- mybatis-config.xml을 만들어줄 위치를 지정해준다.

 

2. MyBatis-config.xml 파일 생성

경로는 위에 지정해주었던 resource/spring/config/mybatis-config.xml에 파일을 만들어준다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration 
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
 "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- 선언문에 콘피규레이션으로 하고, dtd가 안의 속성들을 쓸 수 있도록 기술해놓음 -->  
<configuration>


</configuration>

 

3. Mapper 파일 등록

<configuration>
	<!-- 타입 별칭 지정 -->
	<typeAliases>
		<typeAlias type="com.tis.memo.domain.MemoVO" alias="memo"/>
	</typeAliases>

	<!--mapper 파일 등록-->
	<mappers>
		<mapper resource="spring/mapper/MemoMapper.xml" />
	</mappers>
</configuration>

<configuration>에 타입별칭과 mapper를 지정해준다.

4. DAO 생성

com.tis.memo.persistence 패키지 만들기

 

- 인터페이스 생성

package com.tis.memo.persistence;

import com.tis.memo.domain.MemoVO;

import java.util.List;

public interface MemoDAO {
    int insertMemo(MemoVO memo);
    List<MemoVO> listMemo();
    int deleteMemo(int idx);
}

- 인터페이스를 상속 받는 MemoDAOMyBatis 생성

package com.tis.memo.persistence;

import com.tis.memo.domain.MemoVO;
import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

public class MemoDAOMyBatis implements MemoDAO {

    private final String NS = "com.tis.memo.mapper.MemoMapper";

    // property
    // SqlSession을 생성해주는 객체
    private SqlSessionTemplate session;

    public void setSession(SqlSessionTemplate session) {
        this.session = session;
        System.out.println("sqlSessionTemplate주입됨...");
    }

    @Override
    public int insertMemo(MemoVO memo) {
        
    }


    @Override
    public List<MemoVO> listMemo() {
        
    }


    @Override
    public int deleteMemo(int idx) {
        
    }
}

SqlSession을 생성해주는 객체를 만들고

Injection하기 위해 setter 생성해준다.

 

5. root-context.xml에서 SqlSessionTemplate 빈 등록

<!--[3] SqlSessionTemplate빈 등록-->
<bean id="SqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
	<!--얘는 기본 생성자 없어서 인자생성자로 등록해야 한다.-->
	<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>

- 스프링은 SqlSession을 불러올 SqlSessionTemplate을 생성해서 불러와야 한다.

 

6. 메모를 삽입하는 쿼리문을 작성해보자

@Override
    public int insertMemo(MemoVO memo) {
        return session.insert(NS+".insertMemo", memo);
    }

MemoDAOMyBatis에서 오버라이드된 insertMemo에 insert를 작성해준다.

 

7. Mapper 작성

MyBatis-config.xml에서 등록했던 Mapper를 만들어준다. (MemoMapper.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.tis.memo.mapper.MemoMapper"> <!-- 임의로 정의 가능, 패키지 같은 의미라고 생각 -->
	<insert id="insertMemo" parameterType="memo">
		<!--insert into memo values (memo_seq.nextval, #{name}, #{msg:VARCHAR}, sysdate)-->
		<selectKey keyProperty="idx" order="BEFORE" resultType="int">
			select memo_seq.nextval from dual
		</selectKey>
		<!-- 시퀀스로 증가한 값을 MemoVO의 idx 프로퍼티에 담아주겠다는 의미-->
			insert into memo values (#{idx},#{name},#{msg:VARCHAR}, sysdate)
	</insert>
</mapper>

insert문을 작성해준다.

 

8. MemoInsertController 작성

package com.tis.memo.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.tis.memo.domain.MemoVO;
import com.tis.memo.persistence.MemoDAO;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class MemoInsertController extends DAOBase implements Controller {
	
    private MemoDAO memoDao;

	@Override
	public void setMemoDao(MemoDAO memoDao) {
		this.memoDao = memoDao;
	}


	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 사용자가 입력한 값 받기
		String name = request.getParameter("name");
		String msg = request.getParameter("msg");

		// 유효성 체크
		if(name == null || msg == null || name.trim().isEmpty()){

			return new ModelAndView("redirect:/memo");
			// 스프링은 default가 forward 이동이다.
			// 따라서 redirect 방식으로 이동하고 싶다면
			// 뷰 앞에 redirect: 을 붙여준다.
		}
		MemoVO memo = new MemoVO(0, name, msg, null);

		// DB 연결해서 insert문 실행 후 그 결과를 반환
		int n = getMemoDao().insertMemo(memo);
		System.out.println("Controller 방금 등록한 글 번호:"+memo.getIdx());

		String str = (n>0)?"등록 성공":"등록 실패";
		String loc = (n>0)?"list":"javascript:history.back()";
		
		ModelAndView mv = new ModelAndView();
		
		// setAttribute 를 addObject가 대신함
		mv.addObject("message", str);
		mv.addObject("loc", loc);
		mv.setViewName("msg");
		// WEB-INF/views/message.jsp
		return mv;

	
	}

}

 

9. memo-context.xml에 MemoInsertController 빈 등록

<bean id="memoAdd" class="com.tis.memo.controller.MemoInsertController" name="/memo/insert">
	<property name="memoDao" ref="memoDao"/>
</bean>

올린 것과 흐름도 정리

 

1. 요청 -> DispatcherServlet이 FrontController역할을 한다.

root-context.xml에 있는 빈들을 메모리에 올린다.

 

2. XXXController로 연결해서 주소창에 매핑되어 있는 이름에 맞는 SubController로 이동한다.

(MemoInsertController)

 

3. Controller에서 DB에서 가져올 데이터가 필요하면 XXXDAO를 통해 DB와 연동 후 데이터를 가져온다.

(MemoDAoMyBatis)

 

4. Controller는 Model이름을 DispatcherServlet에 반환한다.

(list)

 

5. ViewResolver는 Model의 이름 앞 뒤에 접두사, 접미사를 붙여서 /WEB-INF/view/뷰이름.jsp로 만든다.

(ViewResolver는 servlet-context.xml에서 빈으로 등록되어 있다.)

(WEB-INF/view/memo/list.jsp) 

 

6. /WEB-INF/view/뷰이름.jsp 에 해당하는 경로를 찾아서jsp를 불러오고 웹브라우저에 응답해준다.