반응형
도서 쇼핑몰 select
BookController.java
package kr.or.ddit.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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;
/*
Controller 어노테이션
스프링 프레임워크에게 "이 클래스는 웹 브라우저의 요청(request)를
받아들이는 컨트롤러야" 라고 알려주는 것임.
스프링은 servlet-context.xml의 context:component-scan의 설정에 의해
이 클래스를 자바빈 객체로 등록(메모리에 바인딩).
*/
// Slf4j 사용 시 하단의 로깅 사용 가능
@Slf4j
@Controller
public class BookController {
//서비스를 호출하기 위해 의존성 주입(Dependency Injection-DI)
//IoC(Inversion of Control) - 제어의 역전.(개발자가 객체생성하지 않고 스프링이 객체를 미리 생성해놓은 것을 개발자가 요청)
// DI - 의존성 주입(Dependency Injection) : 이미 만들어져 있는 BookServiceImpl.java를 @Service로 가져다씀
@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)의 경로)
*/
ModelAndView mav = new ModelAndView();
// name : title / value = "도서생성"
mav.addObject("title", "도서생성");
// jsp
// <beans:property name="prefix" value="/WEB-INF/views/" />
// <beans:property name="suffix" value=".jsp" />
// prefix(접두어) : /WEB-INF/views/
// suffix(접미어) : .jsp
// /WEB-INF/views/ + book/create + .jsp
// forwarding
mav.setViewName("book/create");
return mav;
}
/*
요청URI : /crate
요청파라미터 : {title=개똥이의 모험, category=소설, price=12000}
요청방식 : post
*/
@RequestMapping(value="/create", method=RequestMethod.POST)
public ModelAndView createPost(BookVO bookVO) {
log.info("bookVO : " + bookVO);
// 도서 등록
int result = this.bookService.createPost(bookVO);
log.info("createPost->result : " + result);
ModelAndView mav = new ModelAndView();
// 데이터
mav.addObject("bookVO", bookVO);
// redirect : 새로운 URL 요청
mav.setViewName("redirect:/list");
return mav;
}
/*
요청URI : /list?keyword=알탄 or /list or /list?keyword=
요청파라미터 : keyword=알탄 or 없음
요청방식 : get
required=false : 선택사항. 파라미터가 없어도 무관
*/
@RequestMapping(value="/list", method=RequestMethod.GET)
public ModelAndView list(ModelAndView mav) {
log.info("list에 왔다");
//도서 목록
List<BookVO> bookVOList = this.bookService.list();
log.info("list->bookVOList : " + bookVOList);
//Model : 데이터
mav.addObject("bookVOList", bookVOList);
//View : jsp
//forwarding : 데이터가 넘어감
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" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<title>도서 목록</title>
</head>
<body>
<h3>도서 목록</h3>
<p>
<a href="/create">도서 등록</a>
</p>
<!-- mav.addObject("bookVOList", bookVOList) -->
<%-- <p>${bookVOList}</p> --%>
<table border="1">
<thead>
<tr>
<th>번호</th><th>제목</th><th>카테고리</th><th>가격</th>
</tr>
</thead>
<tbody>
<!--
forEach 태그? 배열(String[], int[][]), Collection(List, Set) 또는
Map(HashTable, HashMap, SortedMap)에 저장되어 있는 값들을
순차적으로 처리할 때 사용함. 자바의 for, do~while을 대신해서 사용함
var : 변수
items : 아이템(배열, Collection, Map)
varStatus : 루프 정보를 담은 객체 활용
- index : 루프 실행 시 현재 인덱스(0부터 시작)
- count : 실행 회수(1부터 시작. 보통 행번호 출력)
-->
<!-- data : mav.addObject("bookVOList", bookVOList); -->
<!-- bookVOList => List<BookVO> -->
<!-- row : bookVO 1행 -->
<c:forEach var="bookVO" items="${bookVOList}" varStatus="stat">
<tr>
<td>${stat.count}</td>
<td>${bookVO.title}</td>
<td>${bookVO.category}</td>
<td><fmt:formatNumber value="${bookVO.price}" pattern="#,###" />원</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
BookService.java
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.BookVO;
public interface BookService {
// 도서 등록
public int createPost(BookVO bookVO);
// 도서 목록
public List<BookVO> list();
}
BookServiceImpl.java
package kr.or.ddit.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.or.ddit.dao.BookDao;
import kr.or.ddit.service.BookService;
import kr.or.ddit.vo.BookVO;
//서비스 클래스 : 비즈니스 로직
//스프링 MVC 구조에서 Controller와 DAO를 연결하는 역할
/*
스프링 프레임워크는 개발자가 직접 클래스를 생성하는 것을 지양하고,
* 프링은 인터페이스를 좋아해. 자꾸자꾸 좋아지면 Impl은 어떡해
인터페이스를 통해 접근하는 것을 권장하고 있기 때문.(확장성)
그래서 서비스 레이어(계층)는 인터페이스(BookService)와 클래스(BookServiceImpl)를 함께 사용함
Impl : implement의 약자
*/
//"프링아 이 클래스 서비스 클래야"라고 알려주자. 프링이가 자바빈으로 등록해줌.
@Service
public class BookServiceImpl implements BookService{
//데이터베이스 접근을 위해 BookDao 인스턴스를 주입받자
//DI(Dependency Injection):의존성 주입
//IoC(Inversion of Control):제어의 역전
@Autowired
BookDao bookDao;
// 메서드 재정의
@Override
public int createPost(BookVO bookVO) {
return this.bookDao.createPost(bookVO);
}
@Override
public List<BookVO> list() {
return this.bookDao.list();
}
}
BookDao.java
package kr.or.ddit.dao;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import kr.or.ddit.vo.BookVO;
//매퍼xml(book_SQL.xml)을 실행시키는
//DAO(Data Access Object) 클래스
//Repository 어노테이션 : 데이터에 접근하는 클래스
//스프링이 데이터를 관리하는 클래스라고 인지하여 자바빈으로 등록하여 관리함
@Repository
public class BookDao {
//DI(Dependency Injection) : 의존성 주입
//개발자가 new 키워드를 통해 직접 객체를 생성하지 않고!!!
//스프링이 미리 만들어 놓은(서버 실행 시 스프링이 미리 xml을 읽어
//객체를 인스턴스화 해놓음)
//sqlSessionTemplate 타입 객체를 BookDao 객체에 주입함
@Autowired
SqlSessionTemplate sqlSessionTemplate;
public int createPost(BookVO bookVO) {
//book_SQL.xml 파일의 namespace가 book이고, id가 insert인
//태그를 찾아 그 안에 들어있는 sql을 실행함
//bookVO=>{"bookId":"","title":"총알탄 개똥이","category":"소설","price":10000,"insertDate":""}
//insert,update,delete는 반영된 건수가 return됨
//insert성공 : 1이상, 실패면 0
// book_SQL.xml의 book 안의 createPost를 찾아감
return this.sqlSessionTemplate.insert("book.createPost", bookVO);
}
//도서 목록
public List<BookVO> list() {
//.selectList("namespace.id",파라미터)
return this.sqlSessionTemplate.selectList("book.list");
}
}
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">
<!-- MyBatis에서 제공해주는 데이터 입력을 나타내는 태그
1) 드루와 : Dao 객체가 던진 데이터타입.parameterType만 씀
2) 가즈아 : Dao 객체의 메소드 쪽으로 리턴할 타입.
- resultType : vo, hashMap, String, int
- resultMap : MyBatis의 resultMap 태그를 사용
-->
<!-- bookVO(전)=>{"bookId":0,"title":"총알탄 개똥이","category":"소설","price":10000,"insertDate":""} -->
<!-- bookVO(후)=>{"bookId":1,"title":"총알탄 개똥이","category":"소설","price":10000,"insertDate":""} -->
<!-- 마이바티스 쿼리 XML에 전달되면 샵{title}을 "총알탄 개똥이"로 자동 변환함 -->
<insert id="createPost" parameterType="bookVO">
<!-- 니키? 내키? 아니! 우리키!! -->
<!-- 키를 높이면 락(rok)커가 될 수 있을까?
order : BEFORE(쿼리를 실행하기 전에 먼저 selectKey를 실행)
resultType : selectKey 쿼리를 실행 한 결과 타입
keyProperty : bookVO의 멤버변수(결과를 담을)
-->
<!-- insert문을 실행하기 전에 실행됨 -->
<selectKey resultType="int" order="BEFORE" keyProperty="bookId">
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>
<!-- 도서 목록 -->
<!-- bookVO의 값으로 매핑되게 작업해놓음 -->
<select id="list" resultType="bookVO">
SELECT BOOK_ID, TITLE, CATRGORY, PRICE, INSERT_DATE
FROM BOOK
ORDER BY BOOK_ID DESC
</select>
</mapper>
+ css와 js 추가해야함!
반응형
'스프링 프레임워크' 카테고리의 다른 글
[스프링 프레임워크] 6장 도서 쇼핑몰 delete (0) | 2024.04.24 |
---|---|
[스프링 프레임워크] 5장 도서 쇼핑몰 detail(상세, 수정) (0) | 2024.04.24 |
[스프링 프레임워크] 3장 도서 쇼핑몰 insert (0) | 2024.04.23 |
[스프링 프레임워크] 2장 DB 연결 (0) | 2024.04.23 |
[스프링 프레임워크] 1장 스프링 프레임워크 (롬복 설치와 기본 설정 추가) (0) | 2024.04.22 |