romworld

Spring 06 - 도서 CRUD(5) - delete,select(책목록) PL/SQL문 본문

Spring

Spring 06 - 도서 CRUD(5) - delete,select(책목록) PL/SQL문

inderrom 2023. 1. 25. 14:20

<book_SQL.xml> 추가

  	<!-- parameterType : int,String,bookVO,hashMap  -->
  	<delete id="deletePost" parameterType="bookVO">
  		DELETE FROM BOOK
		WHERE BOOK_ID IN(#{bookId}) 
  	</delete>

 

<detail.jsp> 추가

<!-- 
method
1)GET : 데이터를 변경하지 않을 때. 목록/상세보기
2)POST : 데이터를 변경할  때 . 입력/수정/삭제

--1) 단일행 : =,<,>,<=,>=,!=,<>
--2) 다중행 : IN(교집합),ANY(OR연산자),ALL(AND연산자),EXISTS(교집합)
 --> 	
 		<form action="/delete" method="post">
 			<!-- 폼 데이터 -->
 			<input type="hidden" name="bookId" value="${bookId}" />
 			<button type="submit">삭제</button>
 		</form>
 	</p>

 

 

<BookDao.java> 추가

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

 

<BookServieImpl> 추가

// 책 삭제하기
	@Override
	public int deletePost(BookVO bookVO) {
		return this.bookDao.deletePost(bookVO);
        }

 

<BookService> 추가

// 도서 삭제하기
	public int deletePost(BookVO bookVO);

 

 

<BookController.java> 추가

// 요청 URI : /delete
	// 요청 파라미터 : {"bookId" : "2"}
	// <input type="hidden" name="bookId" value="2" />
	@RequestMapping(value="/delete",method=RequestMethod.POST)
	public ModelAndView deletePost(@ModelAttribute BookVO bookVO,
				ModelAndView mav) {
		log.info("bookBO : " + bookVO);
		// 삭제SQL 실행 후 반영된 행의 수
		int result = this.bookService.deletePost(bookVO);
		
		if(result > 0) { // 삭제 성공
			// 목록으로 요청 이동(상세페이지가 없으므로..)
			mav.setViewName("redirect:/list");
		}else { // 삭제 실패
			// 상세페이지로 이동
			mav.setViewName("redirect:/detail?bookId="+bookVO.getBookId());
		}
		
		return mav;
	}

 


[여기서 잠깐 SQL 상식]

 

PL/SQL 종류
  • Package
  • User Function
  • Stroed Procedure
  • Trigger
  • Anonymous Block

실습을 위해 더미 데이터 편하게 집어넣자!

--PL/SQL : Procedual Language(절차적인 언어)/Structed Query Language
--절차적인 : 분기, 반복, 변수
--DECLARE, EXCEPTION : 선택
--BEGIN, END : 필수
/
DECLARE
    --I INT; 생략 가능
BEGIN
    --I : 자동선언 정수형 변수
    FOR I IN 1..30 LOOP
    INSERT INTO BOOK(BOOK_ID, TITLE, CATEGORY, PRICE, INSERT_DATE, CONTENT)
    VALUES(
        (SELECT NVL(MAX(BOOK_ID),0) + 1 FROM BOOK),
        '제목'||I,'카테고리'||I,10000,SYSDATE,'내용'||I
    );
    END LOOP;
    COMMIT;
    EXCEPTION
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('오류 발생 : ' || SQLERRM);
END;
/

--널이 있으면 널봐라
SELECT NVL(MAX(BOOK_ID),0) + 1 FROM BOOK;
/
SET SERVEROUTPUT ON;
/
DECLARE
    --I INT;
    ID VARCHAR2(10);
BEGIN
    SELECT BOOK_ID INTO ID FROM BOOK;
    --I : 자동선언정수형 변수
    FOR I IN 1..30 LOOP
        INSERT INTO BOOK(BOOK_ID, TITLE, CATEGORY, PRICE, INSERT_DATE, CONTENT)
        VALUES(
            (SELECT NVL(MAX(BOOK_ID),0) + 1 FROM BOOK),
            '제목'||I,'카테고리'||I,10000,SYSDATE,'내용'||I
        );
    END LOOP;
    COMMIT;
    --정의된 예외
    --정의되지 않은 예외
    --사용자 정의 예외
    EXCEPTION
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('오류 발생 : ' || SQLERRM);
END;
/

 

정렬하는 법 

WITH T AS(
    SELECT ROW_NUMBER() OVER(ORDER BY BOOK_ID DESC) RNUM
    --, ROWNUM NUM1
    , BOOK_ID, TITLE, CATEGORY, PRICE, INSERT_DATE, CONTENT
    FROM   BOOK
)
SELECT T.RNUM, T.BOOK_ID, T.TITLE, T.CATEGORY, T.PRICE
     , T.INSERT_DATE, T.CONTENT 
FROM   T

 

 

 


책 목록

 

<book_SQL.xml> 추가

	<!-- 
  	책 목록
  	 -->
  	<select id="list" resultType="bookVO">
  		WITH T AS(
    		SELECT ROW_NUMBER() OVER(ORDER BY BOOK_ID DESC) RNUM
   		 , BOOK_ID, TITLE, CATEGORY, PRICE, INSERT_DATE, CONTENT
    		FROM   BOOK
		)
		SELECT T.RNUM, T.BOOK_ID, T.TITLE, T.CATEGORY, T.PRICE
		     , T.INSERT_DATE, T.CONTENT 
		FROM   T
  	</select>

 

<BookVO.java> 추가

- private int rnum 추가

- getter/setter

- toString

package kr.or.ddit.vo;

import java.util.Date;

// 자바빈 클래스
// 1) 멤버변수 2) 기본생성자 3) getter/setter메소드
public class BookVO {
	private int rnum;
	private int bookId;
	private String title;
	private String category;
	private int price;
	private Date insertDate;
	private String content;
	
	// 기본생성자. 생략가능
	public BookVO() {}

	// getter/setter 메서드
	
	public int getRnum() {
		return rnum;
	}

	public void setRnum(int rnum) {
		this.rnum = rnum;
	}
	
	public int getBookId() {
		return bookId;
	}

	public void setBookId(int bookId) {
		this.bookId = bookId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public Date getInsertDate() {
		return insertDate;
	}

	public void setInsertDate(Date insertDate) {
		this.insertDate = insertDate;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	@Override
	public String toString() {
		return "BookVO [rnum=" + rnum + ", bookId=" + bookId + ", title=" + title + ", category=" + category
				+ ", price=" + price + ", insertDate=" + insertDate + ", content=" + content + "]";
	}
	
}

 

<BookDao.java> 추가

	// 책 목록
	// 리턴 타입 :List<BookVO>
	public List<BookVO> list(){
		//.selectOne() : 1행(상세보기)
		//.selectList() : 여러행(목록)
		return this.sqlSessionTemplate.selectList("book.list");
	}

 

<BookServiceImpl.java>

// 책 목록
	// 리턴 타입 :List<BookVO>
	@Override
	public List<BookVO> list(){
		return this.bookDao.list();
	}

<BookService.java>

// 도서 목록보기
	public List<BookVO> list();

 

<BookController.java>

	// 요청URI : /list
	// 요청 파라미터 : {}
	// 방식 : get
	@RequestMapping(value="/list",method=RequestMethod.GET)
	public ModelAndView list(ModelAndView mav) {
		List<BookVO> bookVOList = this.bookService.list();
		
		log.info("bookVOList : " + bookVOList);
		// 데이터
		mav.addObject("data", bookVOList);
		// jsp(뷰) : book폴더에 있는 list.jsp를 forwarding(jsp를 해석, 컴파일하여 html로 리턴)
		mav.setViewName("book/list");
		
		return mav;
	}

 

 

데이터를 찍어보면

<list.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>
<script type="text/javascript" src="/resources/js/jquery.3.6.0.js"></script>
<title>도서관리시스템</title>
</head>
<body>
${data}
</body>
</html>

이런식으로 값이 나온다.

 

 

<list.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>
<script type="text/javascript" src="/resources/js/jquery.3.6.0.js"></script>
<title>도서관리시스템</title>
</head>
<body>
	<table border="1">
		<thead>
			<tr>
				<th>번호</th>
				<th>제목</th>
				<th>카테고리</th>
				<th>가격</th>
			</tr>
		</thead>
		<!-- 
			forEach태그? 배열(String[][],int[][],Collection(List,Set)또는
				Map(HashTable, HashMap, SortedMap)에 저장되어 있는 값들을
				순차적으로 처리할 때 사용함. 자바의 for, do-while을 대신하여 사용
			
			data : mav.addObject("data", bookVOList)	
			data : List<BookVO>
			var : 변수(variable)
			items : 아이템(배열, Collection, Map)
			varStatus : 루프 정보르 담은 객체
				- index : 루프(반복) 실행 시 현재 인덱스(0부터 시작)
				- count : 실행 회수(1부터 시작, 보통 행번호를 출력)
		 -->
		<tbody>
			<c:forEach var="bookVO" items="${data}" varStatus="stat">
			<tr>
				<td>${bookVO.rnum}</td>
				<td><a href="/detail?bookId=${bookVo.bookId}">${bookVO.title}</a></td>
				<td>${bookVO.category}</td>
				<td>${bookVO.price}</td>
			</tr>
			</c:forEach>
		</tbody>
	</table>
</body>
</html>

테이블을 만들어주고 실행


 

목록 리스트 링크 추가

수정폼 아래에 추가해준다.

<detali.jsp>

<p><a href="/list">목록</a></p>

 

다시 list를 돌아와서

가격에 천단위 구분기호를 넣어주자

 

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<td><fmt:formatNumber type="number" maxFractionDigits="3"
					value="${bookVO.price}" /></td>

<list.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>
</head>
<body>
	<p>
	<table border="1">
		<thead>
			<tr>
				<th>번호</th>
				<th>제목</th>
				<th>카테고리</th>
				<th>가격</th>
			</tr>
		</thead>
		<!-- 
			forEach태그? 배열(String[][],int[][],Collection(List,Set)또는
				Map(HashTable, HashMap, SortedMap)에 저장되어 있는 값들을
				순차적으로 처리할 때 사용함. 자바의 for, do-while을 대신하여 사용
			
			data : mav.addObject("data", bookVOList)	
			data : List<BookVO>
			var : 변수(variable)
			items : 아이템(배열, Collection, Map)
			varStatus : 루프 정보르 담은 객체
				- index : 루프(반복) 실행 시 현재 인덱스(0부터 시작)
				- count : 실행 회수(1부터 시작, 보통 행번호를 출력)
		 -->
		<tbody>
			<c:forEach var="bookVO" items="${data}" varStatus="stat">
			<tr>
				<td>${bookVO.rnum}</td>
				<td><a href="/detail?bookId=${bookVo.bookId}">${bookVO.title}</a></td>
				<td>${bookVO.category}</td>
				<td><fmt:formatNumber type="number" maxFractionDigits="3"
					value="${bookVO.price}" /></td>
			</tr>
			</c:forEach>
		</tbody>
	</table>
	</p>
	<p>
		<a href="/create">책 생성</a>
	</p>
</body>
</html>

 

Comments