책 상세보기 / 수정하기

조수경·2022년 1월 28일
0

Spring

목록 보기
8/43

detail.jsp : 상세보기 폼을 보여주는곳

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>
<html>
<head>
<title>책 상세</title>
</head>
<body>
<h1>책 상세</h1>
<p>제목 : ${data.title}</p>
<p>카테고리 : ${data.category}</p>
<p>가격 : ${data.price}</p>
<p>입력일 : ${data.insertDate}</p>
<p><a href="/update?bookId=${data.bookId}">수정</a></p>
<p><a href="/list">목록으로</a>
</body>
</html>

update.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- 
BookVO 
[bookId=3, title=해리포터, category=소설, price=15000, insertDate=2022-01-28 11:21:37.0]

BookController에서 mav 객체에 data라는 이름으로 select검색 결과를 넣었으므로..
	mav.addObject("data", bookVO)
달러{data.title} 형식으로 사용하면 됨
-->
<!DOCTYPE html>
<html>
<head>
<title>책  수정하기</title>
</head>
<body>
<h1>책 수정</h1>
<!-- action이 없으면 /update를 재요청한다! 단, 메서드는 post로 바뀜 -->
<form method="post">
	<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="text" name="price"
			value="${data.price}" /></p>
	<p>
		<input type="submit" value="저장" />&nbsp;
		<input type="button" value="취소" 
			onclick="javascript:location.href='/detail?bookId=${data.bookId}'" />
	</p>
</form>
</body>
</html>

BookController.java : 상세보기 컨트롤러

//book 상세 보기 
	//파라미터목록(쿼리스트링) : bookId=1
	//map = {bookId,1}
	@RequestMapping(value = "/detail", method = RequestMethod.GET) //요청을 리퀴러 메핑해준다
	public ModelAndView detail(@RequestParam Map<String,Object> map) {
		logger.info("map:" + map);
		
		BookVO bookVO = new BookVO();
		bookVO.setBookId(Integer.parseInt((String)map.get("bookId")));
		//{bookId:1, 나머지는 null}
		logger.info("bookVO(before) : "+ bookVO.toString());
		
		//상세보기 데이터 가져오기
		bookVO = this.bookService.detail(bookVO);
		//{bookId:1, 나머지도 있음}
		logger.info("bookVO(after) : "+ bookVO.toString());
		
		ModelAndView mav = new ModelAndView();
		// book/detail : 뷰 경로
		// forwarding방식임!! : 여기는 데이터를 넣을 수 있음
		mav.addObject("data",bookVO);  //데이터를 담음
		mav.setViewName("book/detail"); 
		
		return mav;
	}

BookController.java : 수정하기 컨트롤러

	// /update?bookId=3
	//쿼리스트링  : bookId=3
	//map : {bookId:3}
	//책 수정 화면 = 책 입력 화면(jsp) + 책 상세 서비스 로직
	@RequestMapping(value="/update", method=RequestMethod.GET)
	public ModelAndView update(@RequestParam Map<String, String> map) {
		logger.info("map : "+map);
		//책 상세 서비스 로직 사용
		BookVO bookVO = new BookVO();
		bookVO.setBookId(Integer.parseInt(map.get("bookId")));
		bookVO = this.bookService.detail(bookVO);
		
		ModelAndView mav = new ModelAndView();
		//request.setAttribute("data",bookVO);
		mav.addObject("data",bookVO);
		//forwarding
		mav.setViewName("book/update");
		
		return mav;
	
	}
	
	//책 수정 post
	@RequestMapping(value = "/update",method = RequestMethod.POST)
	public ModelAndView updatePost(@ModelAttribute BookVO bookVO,
			ModelAndView mav) {//멤버면수와 네브를?같이 쓰면 이게 가능해짐
		logger.info("bookVO : " + bookVO.toString());
		//true : update성공, false : update실패
		boolean isUpdateSuccess = this.bookService.update(bookVO);
		
		if(isUpdateSuccess) {//성공
			//상세페이지로 이동
			mav.setViewName("redirect:/detail?bookId="+bookVO.getBookId());
		}else {//실패
			//책 수정 화면으로 돌아가기
			//방법1)
//			mav.setViewName("redirect:/update?bookId="+bookVO.getBookId());
			//방법2)
			//멥을 만들어서
			Map<String,String> map = new HashMap<String, String>();
			//넣어라
			map.put("bookId", ""+bookVO.getBookId());
			mav=this.update(map);//다이렉트로 호출
		}
		return mav;
	}

BookService

package kr.or.ddit;

public interface BookService {
	//dao에 있는메소드를 그대로 복붙한 것
	//book 테이블로 insert
	public int insert(BookVO bookVO);
	//메소드 시그니처 처리를 하는 것
	//book 상세보기
	public BookVO detail(BookVO bookVO);
	//book 수정하기(메서드 시그니처?)
	public boolean update(BookVO bookVO);
}

BookServiceImpl

package kr.or.ddit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

//어노테이션.. 스프링에게 이 클래스는 서비스 클래스임을 알려줌
//스프링이 자바 빈(java bean)으로 등록하여 관리
@Service
public class BookServiceImpl implements BookService {//클래스 implements 인터페이스
	private static final Logger logger = 
			LoggerFactory.getLogger(BookServiceImpl.class);
	//이미 관리되어있는 객체를 가져다 쓴다
	@Autowired
	BookDao bookDao;
	
	//부모 객체의 메소드를 재정의 하는 것 
	@Override
	//메서드를 재정의 하는거라 오버라이드가 맞음 근데 어디서?
	public int insert(BookVO bookVO) {
		logger.info("bookVO : " + bookVO.toString());
		int affectRowCount = this.bookDao.insert(bookVO);
		
		if(affectRowCount == 1) {//입력이 성공
			//xml에서 selectKey에서 세팅된 그 값(max(book_id)+1)
			return bookVO.getBookId();
		}
		//입력 실패
		return 0;
	}

	//책 상세보기
	@Override
	public BookVO detail(BookVO bookVO) {
		return this.bookDao.detail(bookVO);
		//컨트롤러로 리턴되는 것
	}
	
	//책 수정하기
	@Override
	public boolean update(BookVO bookVO) {
		return this.bookDao.update(bookVO);
	}
	

}

BookDao.java

package kr.or.ddit;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


//mapper xml을 실행해주는 클래스.
//어노테이션을 붙여서 이 클래스는 데이터에 접근하는 클래스야~
//Spring에게 알려줘!
//Spring이 데이터를 관리하는 클래스라고 인지해서 자바 빈(java bean)으로 등록해서 관리
@Repository
public class BookDao { //사람
	//sqlSessionTempate 사용
	/*
	 * new 키워드를 통해 직접 생성 안했는데 객체가 생성이 됨!! 싱기방구 
	 * 이게 바로 의존성 주입임!!!(Dependency Injection - DI)
	 * DI로 주입 받는 것임
	 * 스프링이 이미 만들어 놓은 sqlSessionTemplate 타입 객체를 BookDao 객체에 주입
	 * 이 과정은 자동으로 스프링에서 실행되며, 개발자가 직접 객체를 생성하지 않음(이것이 바로 IoC: 제어의 역전)
	 * 
	 */
	
	@Autowired//자동 주입
	SqlSessionTemplate sqlSessionTemplate;//미리 만들어 놓은 백신(root컨택스트에서 온것)
	
	public int insert(BookVO bookVO) {
		//book_SQL.xml 파일에서
		//namespace="book"
		//id="insert"
		//book.insert : 매퍼 쿼리 명
		//bookVO : 두 번째 인수.. 쿼리에 전달할 데이터(String, int, VO, Map)
		return this.sqlSessionTemplate.insert("book.insert", bookVO);//마이바티스가 만든 메서드
	}
	
	//책 상세보기
	public BookVO detail(BookVO bookVO) {
		//.selectOne 메소드 : 1행을 가져올때 사용
		// 결과 행 수가 0이면 null반환
		// 결과 행 수가 2이상일 때 TooManyResultsException 예외 발생
		//(namespace.id, 파라미터)
		return sqlSessionTemplate.selectOne("book.detail",bookVO);
	}
	
	//책 수정하기
	public boolean update(BookVO bookVO) {
		//(namespace.id, 파라미터)
		//update 후에 영양받은 행의 수를 받음
		int result = this.sqlSessionTemplate.update("book.update",bookVO);
		//0보타 크다는 것은 update가 성공했다는 의미
		return result > 0;
	}
	
}

book_SQL.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="book">
<!-- 클래스이름까지 다쓰는게 파라미터 타입 -->
	<!-- bookId값은 어떻게 넣을까? -->
	<!-- selectKey란?
		마이바티스는 쿼리 실행 시 파라미터를 치환해줌
		selectKey 전 : {"title":"검은태양", "category":"드라마", "price":10000}
		selectKey 후 : {"bookId":1, "title":"검은태양","category":"드라마" ,"price":10000}
		
	 -->
	<insert id="insert" parameterType="kr.or.ddit.BookVO">
		<!-- ******* -->
		<!-- 1이 bookId안에 들어감 -->
		<selectKey order="BEFORE" keyProperty="bookId" resultType="integer">
			SELECT NVL(MAX(BOOK_ID),0)+1 FROM BOOK
		</selectKey>
			INSERT INTO BOOK(BOOK_ID,TITLE,CATEGORY,PRICE,INSERT_DATE)
			VALUES(#{bookId},#{title},#{category},#{price},SYSDATE)
	</insert>
	<!-- 책 상세보기 -->
	<select id="detail" parameterType="bookVO" resultType="bookVO">
		select BOOK_ID,TITLE,CATEGORY,PRICE,INSERT_DATE
		from book
		where book_id=#{bookId}
	</select>
	
	<!-- 책 수정하기, update태그는 UPDATE 쿼리를 실행하기 위한 마이바티스 태그 -->
	<update id="update" parameterType="bookVO">
		update book 
		set TITLE=#{title},CATEGORY=#{category},PRICE=#{price}
		where book_id=#{bookId}
	</update>
	
</mapper>



profile
신입 개발자 입니다!!!

0개의 댓글