구현 순서
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로 이동
'Java Web Programming > 6. Spring | MyBatis' 카테고리의 다른 글
[SerlvetConfig/SerlvetContext] 다시 한 번 공부해보자! (0) | 2020.11.11 |
---|---|
[SpringMVC/MyBatis] Spring 설정 파일을 분리하여 적용해보기 + DB Sequence (0) | 2020.11.10 |
[SpringMVC/MyBatis] SpringMVC + 마이바티스 연동 연습 1 (0) | 2020.11.09 |
[SpringMVC] Ajax적용 - Annotation기반의 SpringMVC 연습 3 (0) | 2020.11.09 |
[SpringMVC] has a 관계 - Annotation기반의 SpringMVC 연습 2! (0) | 2020.11.09 |