romworld

Spring 05 - 도서CRUD(4) - update, JSTL (fmt) 본문

Spring

Spring 05 - 도서CRUD(4) - update, JSTL (fmt)

inderrom 2023. 1. 20. 17:35

먼저 <detail.jsp> 에서 

수정폼을 추가하자!

<p><a href="/update?bookId=${bookId}">수정폼</a></p>
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/resources/js/jquery.3.6.0.js"></script>
<title>도서관리시스템</title>
<script type="text/javascript" src="/resources/ckeditor/ckeditor.js"></script>
</head>
<body>
<!-- mav.addObject("data", data); => bookVO 데이터 -->
<%-- ${data} --%>
<!-- <hr /> -->
<!-- mav.addObject("bookId", data.getBookId());기본키 값(int 타입) -->
<%-- ${bookId} --%>
<!-- 
JSTL(JSP Standard Tag Library) : 개발자가 자주 사용하는 패턴을 모아놓은 집합
=> BookController에서 보내준 데이터를 뷰에 표현하도록 도와줌
JSTL은 maven에서 설정되어 있음 => pom.xml => jstl
 -->
 	<h1>책 상세</h1>
 	<p>제목 : ${data.title} </p>
 	<p>카테고리 : ${data.category}</p>
 	<p>가격 : ${data.price}</p>
 	<p>입력일 : ${data.insertDate}</p>
 	<p>내용 : 
 	<textarea name="content" rows="5" cols="30" readonly>${data.content}</textarea>
 	</p>
 	<p><a href="/update?bookId=${bookId}">수정폼</a></p>
 <script type="text/javascript">
 CKEDITOR.replace("content");
// CKEDITOR.instances['content'].setReadOnly(false);
 </script>
</body>
</html>

 


<BookController.java>

update 메소드 추가

// 요청URI : /updata?bookId=2
	// 요청URL : /update
	// 요청파라미터 : bookId=2
	
	// @ModelAttribute VO가 있는 곳에 붙힌다. 생략 가능
	@RequestMapping(value="/update", method=RequestMethod.GET)
	public ModelAndView update(@ModelAttribute BookVO bookVO,
			ModelAndView mav) {
		log.info("bookVO : " + bookVO);
		
		// 책 수정 화면 = 책 입력 화면 + 책 상세 데이터
		// 책 입력 화면 양식을 그대로 따라가고, 빈 칸을 데이터로 채워주면 됨
		BookVO data = bookService.detail(bookVO);
		log.info("data : " + data);
		
		// ModelAndView mav = new ModelAndView(); 를 해줘도 되고
		// 파라미터에 넣어서 변수를 호출해도 된다. (mav.addObject)
		// model : 데이터를 jsp로 넘겨줌
		mav.addObject("data", data);
		
		// View : jsp의 경로
		// WEB-INF/views/ + book/update + .jsp
		// forwarding
		mav.setViewName("book/update");
		
		return mav;
	}

package kr.or.ddit.controller;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import kr.or.ddit.service.BookService;
import kr.or.ddit.vo.BookVO;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.dbcp2.BasicDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;

/*	Controller 어노테이션
스프링 프레임워크에게 "이 클래스는 웹 브라우저(클라이언트)의 요청(request)을
받아들이는 컨트롤러야" 라고 알려주는 것임.
스프링은 servlet-context.xml의 context:component-scan의 설정에 의해
이 클래스를 자바빈 캑체로 미리 등록 (메모리에 바인딩)
 */
// slf4j를 쓰면  lombok을 쓸 수 있다.
@Slf4j
@Controller	
public class BookController {
	// 서비스를 호출하기 위해 의존성 주입 (Dependency Injection -DI)
	@Autowired
	BookService bookService;
	
	// 요청 URI : /create
	// 방법 : get
	// 요청 - (매핑) - 메소드
	@RequestMapping(value="/create", method=RequestMethod.GET)
	public ModelAndView create() {
		/* ModelAndView
		   1) Model : Controller가 반환할 데이터(String, int ,List, Map, VO ..)를 담당.
		   2) View : 화면을 담당(뷰(View : jsp)의 경로).jsp파일의 위치
		*/
		ModelAndView mav = new ModelAndView();
		/*
		 <beans:property name="prefix" value="/WEB-INF/views/" />
		 <beans:property name="suffix" value=".jsp" />
		 prefix + 뷰경로 +.jsp가 조립
		servlet-context에서  중복 되는 주소를 지운다.
		/WEB-INF/views/book/create.jsp
		 */
		// forwarding
		mav.setViewName("book/create");
		return mav;
	}
	
	/*
	 요청URI : /cretae?title=롬이야기&category=소설&price=10000
	요청URL : /create
	요청파라미터 : {title=롬이야기&category=소설&price=10000}
	요청방식 : post
	
	bookVO{bookId:null,title:롬이야기,category:소설price:10000,insertDate:null
					content:null}
	private int bookId;
	private String title;
	private String category;
	private int price;
	private Date insertDate;
	private String content;
	*/
	@RequestMapping(value="/create", method=RequestMethod.POST)
	public ModelAndView createPost(BookVO bookVO, ModelAndView mav) {
		log.info("bookBO : " + bookVO.toString());
		//<selectKey resultType="int" order="BEFORE" keyProperty="bookId">
		//1 증가된 기본키 값을 받음
		int bookId = bookService.createPost(bookVO);
		
		log.info("bookId :" + bookId);
		
		if(bookId <1) { // 등록 실패
			// /create로 요청을 다시 함 => uri주소가 바뀜
			mav.setViewName("redirect:/create");
			
		}else {// 등록 성공 : 상세보기 페이지로 이동
			mav.setViewName("redirect:/detail?bookId=" + bookId);
		}
		
		return mav;
	}
	
	// 책 상세보기
	// 요청URI : /detail?bookId=2
	// 요청URI : /detail
	// 요청파라미터 : (HTTP파라미터=QueryString)bookId=2
	//bookVO{bookId:2,title:null,category:nullprice:0,insertDate:null
	//content:null}
	@RequestMapping(value="/detail",method=RequestMethod.GET)
	public ModelAndView detail(BookVO bookVO, ModelAndView mav) {
		log.info("bookVO : " + bookVO );
		
		BookVO data = bookService.detail(bookVO);
		log.info("data : " + data);
		
		// ModelAndView mav = new ModelAndView(); 를 해줘도 되고
		// 파라미터에 넣어서 변수를 호출해도 된다. (mav.addObject)
		// model : 데이터를 jsp로 넘겨줌
		mav.addObject("data", data);
		mav.addObject("bookId", data.getBookId()); // 기본키 값
		
		/* servlet-context.xml에서 매핑 되어서 주소를 book/detail로 생략해서 쓰기 가능
		 <beans:property name="prefix" value="/WEB-INF/views/" />
		 <beans:property name="suffix" value=".jsp" />
		 prefix + 뷰경로 +.jsp가 조립
		servlet-context에서  중복 되는 주소를 지운다.
		/WEB-INF/views/book/create.jsp
		 */
		
		//forwarding => detail.jsp를 해석/컴파일 => html로 크롬에게 리턴. 데이터 전달 기능
		mav.setViewName("book/detail");
		
		return mav;
	}
	
	// 요청URI : /updata?bookId=2
	// 요청URL : /update
	// 요청파라미터 : bookId=2
	
	// @ModelAttribute VO가 있는 곳에 붙힌다. 생략 가능
	@RequestMapping(value="/update", method=RequestMethod.GET)
	public ModelAndView update(@ModelAttribute BookVO bookVO,
			ModelAndView mav) {
		log.info("bookVO : " + bookVO);
		
		// 책 수정 화면 = 책 입력 화면 + 책 상세 데이터
		// 책 입력 화면 양식을 그대로 따라가고, 빈 칸을 데이터로 채워주면 됨
		BookVO data = bookService.detail(bookVO);
		log.info("data : " + data);
		
		// ModelAndView mav = new ModelAndView(); 를 해줘도 되고
		// 파라미터에 넣어서 변수를 호출해도 된다. (mav.addObject)
		// model : 데이터를 jsp로 넘겨줌
		mav.addObject("data", data);
		
		// View : jsp의 경로
		// WEB-INF/views/ + book/update + .jsp
		// forwarding
		mav.setViewName("book/update");
		
		return mav;
	}
}

 

<update.jsp>

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/resources/ckeditor/ckeditor.js">
</script>
<meta charset="UTF-8">
<title>책 수정하기</title>
</head>
<body>
<h1>책 수정</h1>
<!-- 폼페이지 
mav.addObject("data",data); // data: bookVO
-->
<!-- 
요청URI : /update
요청파라미터 : {bookId:2 tilte=롬이야기,category=소설,price=10000}
요청방식 : post
 -->
<form action="/update" method="post">
	<!-- 폼데이터 -->
	<!-- bookId는 기본키 .. 있어야한다. -->
	<input type="hidden" name="bookId" value="${data.bookId}" /> 
	<p>제목 : <input type="text" name="title" value="${data.title}" required /></p>
	<p>카테고리 : <input type="text" name="category" value="${data.category}" required /></p>
	<p>가격: <input type="number" name="price" value="${data.price}" required /></p>
	<p>내용: <textarea name="content" rows="5" cols="30"">${data.content}</textarea></p>
	<p>
		<input type="submit" value="저장" />
		<input type="button" value="목록" />
	</p>
</form>
<script type="text/javascript">
	CKEDITOR.replace('content');
</script>
</body>
</html>


detail.jsp   날짜 , 가격 출력 방식 변경하기

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 사용하자

 

<detail.jsp>

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/resources/js/jquery.3.6.0.js"></script>
<title>도서관리시스템</title>
<script type="text/javascript" src="/resources/ckeditor/ckeditor.js"></script>
</head>
<body>
<!-- mav.addObject("data", data); => bookVO 데이터 -->
<%-- ${data} --%>
<!-- <hr /> -->
<!-- mav.addObject("bookId", data.getBookId());기본키 값(int 타입) -->
<%-- ${bookId} --%>
<!-- 
JSTL(JSP Standard Tag Library) : 개발자가 자주 사용하는 패턴을 모아놓은 집합
=> BookController에서 보내준 데이터를 뷰에 표현하도록 도와줌
JSTL은 maven에서 설정되어 있음 => pom.xml => jstl
 -->
 	<h1>책 상세</h1>
 	<p>제목 : ${data.title} </p>
 	<p>카테고리 : ${data.category}</p>
 	<p>가격 : <fmt:formatNumber type="number" pattern="###,###" maxFractionDigits="0"
 				value="${data.price}"/></p>
 	<p>입력일 : <fmt:formatDate pattern="yyyy.MM.dd HH:mm:ss" 
 				value="${data.insertDate}" /></p>
 	<p>내용 : 
 	<textarea name="content" rows="5" cols="30" readonly>${data.content}</textarea>
 	</p>
 	<p><a href="/update?bookId=${bookId}">수정폼</a></p>
 <script type="text/javascript">
 CKEDITOR.replace("content");
// CKEDITOR.instances['content'].setReadOnly(false);
 </script>
</body>
</html>

가격과 입력일이 변경된 것을 볼 수 있다.


<BookController.java>

/* 
	요청URI : /update
	요청파라미터 : {bookId:2 tilte=롬이야기2,category=소설2,price=11000}
	요청방식 : post
	 */
	@RequestMapping(value="/update", method=RequestMethod.POST)
	public ModelAndView updatePost(BookVO bookVO
			, ModelAndView mav) {
		
		log.info("bookVO(updatePost) : " + bookVO);
		
		return mav;
	}

 

 

 


UPDATE 쿼리문 추가

 

 

 

<book_SQL.xml> 추가

<!-- 책 수정하기. update 태그는 update 쿼리를 실행하기 위한 mybatis 태그  -->
  	<!-- insert/update/delete의 경우 resultType 생략 가능(당연히 int)  -->
  	<update id="updatePost" parameterType="bookVO">
  		UPDATE 	BOOK
		SET 	TITLE=#{title}, CATEGORY=#{category}
				,PRICE=#{price},INSERT_DATE=SYSDATE,CONTENT=#{content}
		WHERE 	BOOK_ID =#{bookId}
  	</update>

 

 

< BookDao.java> 추가

 

// 책 수정하기
	public int updatePost(BookVO bookVO) {
		//.update("namespace.id",파라미터)
		// 반환타입 int : update구문이 반영된 행의 수
		return this.sqlSessionTemplate.update("book.updatePost",bookVO);
	}

 

 

<BookServiceImple.java> 추가

// 책 수정하기
	@Override
	public int updatePost(BookVO bookVO) {
		return this.bookDao.updatePost(bookVO);
	}

 

 

<BookService.java> 추가

 

// 도서 변경하기
	public int updatePost(BookVO bookVO);

 

 

<BookController.java> 수정

	/* 
	요청URI : /update
	요청파라미터 : {bookId:2 tilte=롬이야기2,category=소설2,price=11000}
	요청방식 : post
	 */
	@RequestMapping(value="/update", method=RequestMethod.POST)
	public ModelAndView updatePost(BookVO bookVO
			, ModelAndView mav) {
		
		log.info("bookVO(updatePost) : " + bookVO);
		
		//result는 update문에 반영된 행의 수
		int result = this.bookService.updatePost(bookVO);
		
		if(result > 0) { // 업데이트 성공 -> 책 상세페이지(/detail)로 이동
			mav.setViewName("redirect:/detail?bookId="+bookVO.getBookId());
		}else { // 업데이트 실패 -> 업데이트 뷰페이지(/update)로 이동
			mav.setViewName("redirect:/update?bookId="+bookVO.getBookId());
		}
		
		return mav;
	}

 

데이터를 변경해보고 저장을 눌렀을 떄
변경된 내용이 detail로 가는 경우 성공!

 

Comments