본문 바로가기
Java Web Programming/6. Spring | MyBatis

[SpringMVC/MyBatis] SpringMVC + 마이바티스 연동 연습 2 (JSTL)

by 파프리카_ 2020. 11. 10.
728x90
반응형

구현 순서

1. maven pom 설정

2. Spring config 설정

3. JSP 구성

4. MyBatis 설정 - mapper.xml에 SQL문 기입

5. DAO와 DAOImpl에 메서드 기입 - 어노테이션 표기 (@Repository, @Response)

6. Controller에 메서드 기입 - 어노테이션 표기 (@Controller, @Response, @RequestMapping)

7. JSP 완성


Maven pom 설정 

 

/pom.xml

<dependencies>
  <!-- Spring-Web MVC Framework (SpringMVC, IOC, DI/DL) -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.14.RELEASE</version>
  </dependency>

  <!-- Ajax JSON Library (jackson-databind) -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.5</version>
  </dependency>
  
  <!-- MyBatis Framework -->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.0</version>
  </dependency>

  <!-- Spring과 MyBatis 연동 Framework -->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
  </dependency>

  <!-- DBCP ver.2 -->
  <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.1.1</version>
  </dependency>

  <!-- JDBC(*Spring ver과 같아야한다) -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.14.RELEASE</version>
  </dependency>
  
  <!-- JSTL Library-->
  <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
  </dependency>

</dependencies>

DD (Deploytment Descriptor) 설정

 

/WEB_INF/web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>SpringMVC5-customer</display-name>
   <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  
  <!-- request에 대한 한글처리 -->
  <filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

Spring configure 설정

 

* namespace에서 'context', 'mvc' 체크

 

/WEB_INF/springmvc-servlet.xml

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

	<!-- 1. DBCP 설정 -->
	<bean id="dbcp" class="org.apache.commons.dbcp2.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
		<property name="username" value="scott"/>
		<property name="password" value="tiger"/>
	</bean>
	
	<!--2. SqlSessionFactory 설정 -->
	<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- DBCP(datebase connection pool) 주입 -->
		<property name="dataSource" ref="dbcp"/>
		<!-- MyBatis에서 쓸 mapper loation(path) 주입 -->
		<property name="mapperLocations" value="classpath:/mybatis/config/*.xml"/>
		<!-- Package에 별칭주기 -->
		<property name="typeAliasesPackage" value="org.kosta.model"/>
	</bean>

	<!--3. SqlSessionTemplate설정 : 트랜잭션 제어를 지원-->
	<bean id="SqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg ref="sqlSessionFactoryBean"/>
	</bean>

	<!--4. IOC 설정 : <context:component-scan> :  IOC, DI, DL에 대한 설정-->
	<context:component-scan base-package="org.kosta"></context:component-scan>

	<!--5. SpringMVC 설정-->
	<mvc:annotation-driven/>


	<!--6. ViewResolver 설정 : client에게 응답하는 view에 대한 설정 -->
	<bean id="ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/views/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
	<!-- 의존대상 객체 bean -->
	<bean id="customerDAO" class="org.kosta.model.CustomerDAOImpl">
		<constructor-arg ref="SqlSessionTemplate"/>
	</bean>
</beans>

MyBatis 설정 - mapper (/mybatis.config)

 

src/mybatis/config/customer.xml

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

 	<sql id="selectCustomer">
 		SELECT *
		FROM   spring_customer
 	</sql>
 	
 	<!-- 1. 아이디로 회원정보 찾기 -->
 	<select id="findCustomerById" resultType="customerVO">
 		<include refid="selectCustomer"/>
 		WHERE id=#{value}
 	</select>
 	
 	<!-- 2. 주소로 회원정보 리스트 찾기 -->
 	<select id="findCustomerListByAddress" resultType="customerVO">
 		<include refid="selectCustomer"/>
 		WHERE  address=#{value}
 	</select>
 	
 	<!-- 3. 회원가입 -->
 	<insert id="registerCustomer">
 		INSERT INTO spring_customer
 		VALUES(#{id}, #{name}, #{address})
 	</insert>
</mapper>

SQL

 

1. 테이블 생성 및 값 입력

CREATE TABLE spring_customer(
    id      VARCHAR2(100) PRIMARY KEY,
    name    VARCHAR2(100) NOT NULL,
    address VARCHAR2(100) NOT NULL
)

INSERT INTO spring_customer VALUES('java', '초코초코', '대만');
INSERT INTO spring_customer VALUES('sweet', '카스테라', '대만');

 

2. spring_customer 테이블


Model

 

/org.kosta.model

 

/CustomerVO.java

package org.kosta.model;

public class CustomerVO {
	private String id;
	private String name;
	private String address;
	
	public CustomerVO() {
		super();
	}

	public CustomerVO(String id, String name, String address) {
		super();
		this.id = id;
		this.name = name;
		this.address = address;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Override
	public String toString() {
		return "CustomerVO [id=" + id + ", name=" + name + ", address=" + address + "]";
	}
	
}

/CustomerDAO.java <<interface>>

package org.kosta.model;

import java.util.List;

public interface CustomerDAO {
	CustomerVO findCustomerById(String id);

	List<CustomerVO> findCustomerListByAddress(String address);

	void registerCustomer(CustomerVO vo);
}

 

/CustomerDAOImpl.java

-- annotation --

@Repository - class위

@Resource - instance 변수 위 (SqlSesssionTemplate)

package org.kosta.model;

import java.util.List;

import javax.annotation.Resource;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class CustomerDAOImpl implements CustomerDAO {
	
	@Resource //DI(의존성 주입): spring container로부터 객체를 주입
	private SqlSessionTemplate template;
	
	public CustomerDAOImpl(SqlSessionTemplate template) {
		this.template = template;
	}
	
	// 1. 아이디로 회원 정보 찾기
	@Override
	public CustomerVO findCustomerById(String id) {
		return template.selectOne("customer.findCustomerById", id);
	}
	
	// 2. 주소로 회원정보 리스트 검색
	@Override
	public List<CustomerVO> findCustomerListByAddress(String address) {
		return template.selectList("customer.findCustomerListByAddress", address);
	}
	
	// 3. 회원가입
	@Override
	public void registerCustomer(CustomerVO vo) {
		template.insert("customer.registerCustomer", vo);
	}
}

 


View

 

/index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>spring mvc 연습</title>
</head>
<body>
	<h3>SpringMVC 고객관리</h3>
	
	<!-- 1. 아이디로 회원검색 -->
	<form action="findCustomerById.do">
		아이디 <input type="text" name="id" required="required">
		<input type="submit" value="검색">
	</form>
	<hr>
	
	<!-- 2. 주소에 해당하는 회원정보 리스트 검색
		 - 주소에 해당하는 고객이 한명 이상 존재하면,
		   findbyaddress_ok.jsp에서 JSTL로 아이디, 이름의 리스트 제공
		 - 주소에 해당하는 고객이 없으면,
		   findbyaddress_fail.jsp에서 
		   '[주소]에 사는 회원이 없습니다' alert 후 index로 이동
	 -->
	<form action="findCustomerListByAddress.do">
		주소 <input type="text" name="address" required="required">
		<input type="submit" value="검색">
	</form>
	<hr>
	
	<!-- 3. 회원가입
		 - 등록 후 결과 페이지는 views/register_customer_result.jsp에서
		   '고객 정보가 등록되었습니다' alert
		   (POST 방식만 고객 등록 되도록 처리한다.
		    새로고침 시, 재동작되지 않도록 redirect 이동방식으로 응답한다.)
		 - 만약 고객아이디가 중복된다면, (findCustomerById() 활용)
		   view/duplicatedId_result.jsp에서
		   '고객 아이디가 중복되어, 등록이 불가합니다' alert 후,
		   index.jsp로 이동한다.
	 -->
	<form action="registerCustomer.do" method="POST">
		아이디 <input type="text" name="id" required="required"><br>
		이름 <input type="text" name="name" required="required"><br>
		주소 <input type="text" name="address" required="required"><br>
		<input type="submit" value="가입하기">
	</form>
	
	
</body>
</html>

/views

 

/find_customer_ok.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>
	<h4> 검색 결과 </h4>
	아이디 : ${cvo.id}<br>
	이름 : ${cvo.name}<br>
	주소 : ${cvo.address}<br>
</body>
</html>

 

/find_customer_fail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	alert("${param.id} → 해당 아이디에 대한 회원정보가 없습니다.");
	location.href="index.jsp";
</script>

 

 

/findbyaddress_ok.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- JSTL 선언부 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>주소 목록</title>
</head>
<body>
	<!-- varStatus : index와 count 속성이 있다. 
		 (index는 0부터, count는 1부터 시작)
	 -->
	<h3> ${param.address} 지역의 회원정보 </h3>
	<c:forEach items="${requestScope.list}" var="cvo" varStatus="order">
		번호 : ${order.count} <br>
		아이디 : ${cvo.id} <br>
		이름 : ${cvo.name} <br>
		<br>
	</c:forEach>
</body>
</html>

 

/findbyaddress_fail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	alert("${param.address}에 사는 회원이 없습니다.");
	location.href = "index.jsp"
</script>

 

/register_customer_result.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>
고객정보가 등록되었습니다. <br>
등록된 고객 정보는 다음과 같습니다. <br>
아이디: ${cvo.id} | 이름: ${cvo.name} | 주소: ${cvo.address}
</body>
</html>

 

/duplicatedId_result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<script type="text/javascript">
	alert("${sessionScope.duplitcated_id}는 중복된 아이디이므로, 등록이 불가능합니다.");
	location.href = "${pageContext.request.contextPath}/index.jsp";
</script>

Controller

 

/org.kosta.Controller

 

** redirect방식으로 보내면 request가 유지되지 않기 때문에,

${param.} ${requestScope}로 받아올 수 없다. 만약 유지시키고 싶다면 session에 담아 보내야한다. (${sessionScope.})

하지만 계속 유지되기 때문에 좋은 방법이 아니다.

이를 해결하기 위해서, 새로 Controller를 만들어서 이를 이용하는 것이 적합하다.

 

/CustomerController.java

-- annotation --

@Controller - class 위

@Resource - instance변수 위 (CustomerDAO)

@RequestMapping - method 위

package org.kosta.controller;

import java.util.List;

import javax.annotation.Resource;

import org.kosta.model.CustomerDAO;
import org.kosta.model.CustomerVO;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class CustomerController {
	
	@Resource
	private CustomerDAO customerDAO;
	
	// 1. 아이디로 회원검색
	@RequestMapping("findCustomerById.do")
	public String findCustomerById(Model model, String id) {
		String viewName="";
		// 모델과 연동
		CustomerVO cvo = customerDAO.findCustomerById(id);
		
		if (cvo != null) {
			viewName="find_customer_ok";
			//연동 결과 view에 공유
			model.addAttribute("cvo", cvo);
		} else {
			viewName="find_customer_fail";
		}
		// view로 이동
		return viewName;
	}
	
	//2. 주소로 회원정보 리스트 검색
	@RequestMapping("findCustomerListByAddress.do")
	public ModelAndView findCustomerListByAddress(String address) {
		ModelAndView mv = new ModelAndView();
		//모델과 연동
		List<CustomerVO> list = customerDAO.findCustomerListByAddress(address);
		//연동결과 객체의 결과값이 없는 경우 빈 List가 넘어온다 ( [] )
		if (list.isEmpty()) { //list.size() or list.isEmpty()로 비교
			mv.setViewName("findbyaddress_fail");
		} else {
			//연동결과 view와 공유
			mv.addObject("list", list);
			mv.setViewName("findbyaddress_ok");
		}
		//view로 이동
		return mv;
	}
	
	//3. 회원가입
	@PostMapping("registerCustomer.do")
	public String registerCustomer(CustomerVO customerVO) {
		String viewName = "";
		
		// 중복 여부 확인
		// 중복인 경우
		if (customerDAO.findCustomerById(customerVO.getId()) != null) { 
			viewName="redirect:views/duplicatedId_result.jsp"; 
		} else { //중복이 아닌 경우
			customerDAO.registerCustomer(customerVO); 
			//쿼리스트링 방식으로 registerCustomerResult.do 실행 후
			// + id 보내기
			viewName = "redirect:registerCustomerResult.do?id="+customerVO.getId();
		}
		return viewName;
	}
	
	//registerCustomer에서 중복이 아닌 경우 실행된다.
	@RequestMapping("registerCustomerResult.do")
	public ModelAndView registerCustomerResult(String id) {
		CustomerVO cvo = customerDAO.findCustomerById(id);
		//register_customer_result.jsp에 cvo를 보낸다.
		return new ModelAndView("register_customer_result",
				"cvo", cvo);
	}
	
}

[ 결과 ]

> 홈화면 (index.jsp)

 

> DB에 있는 아이디를 입력하면, find_customer_ok.jsp로 이동

>  DB에 없는 아이디를 입력하면, find_customer_fail.jsp로 이동하여 alert이 뜬 후, index.jsp로 이동

 

DB에 있는 주소를 입력하면, findbyaddress_ok.jsp로 이동하여 회원 목록 나옴

DB에 없는 주소를 입력하면, findbyaddress_fail.jsp로 이동하여 alert이 뜬 후, index.jsp로 이동

 

 DB에 없는 아이디를 입력하면, register_customer_result.jsp로 이동하며 등록된 회원 정보 나옴

 

 DB에 있는 아이디를 입력하면, duplicatedId_result.jsp로 이동하여 alert이 뜬 후, index.jsp로 이동

728x90
반응형