관련 포스팅 :# Spring - 미니쇼핑몰 상품관리 구현해보기(상품목록, 상세보기)
관련 포스팅 :# Spring - 미니쇼핑몰 상품관리 구현해보기(장바구니 담기, 목록, 수정, 삭제)
관련 포스팅 :# Spring - 미니쇼핑몰 상품관리 구현해보기(관리자 로그인, 로그아웃/ 관리자 영역 설정)
관리자 권한으로 상품을 등록하고, 수정, 삭제처리를 구현해보자.
1. View(JSP)
1) 상품등록 페이지 (productWrite.jsp)
구현화면
상품등록페이지의 Jvascript코드
$(document).ready(function(){
// 상품 등록 유효성검사
$("#addBtn").click(function(){
var productName = $("#productName").val();
var productPrice = $("#productPrice").val();
var productDesc = $("#productDesc").val();
var productPhoto = $("#productPhoto").val();
if(productName == "") {
alert("상품명을 입력해주세요");
productName.foucs();
} else if (productPrice == "") {
alert("상품 가격을 입력해주세요");
productPrice.focus();
} else if (productDesc == "") {
alert("상품 설명을 입력해주세요");
productDesc.focus();
} else if (productPhoto == "") {
alert("상품 사진을 입력해주세요");
productPhoto.focus();
}
// 상품 정보 전송
document.form1.action = "${path}/shop/product/insert.do";
document.form1.submit();
});
// 상품 목록이동
$("#listBtn").click(function(){
location.href='${path}/shop/product/list.do';
});
});
상품등록 버튼 클릭이벤트가 발생하면 폼안의 값들을 유효성 검사한 뒤에 서버로 전송
상품목록 버튼 클릭이벤트가 발생하면 상품 목록페이지로 이동
상품등록페이지의 HTML코드
<h2>상품 등록</h2>
<form id="form1" name="form1" enctype="multipart/form-data" method="post">
<table border="1">
<tr>
<td>상품명</td>
<td><input type="text" name="productName" id="productName"></td>
</tr>
<tr>
<td>가격</td>
<td><input type="text" name="productPrice" id="productPrice"></td>
</tr>
<tr>
<td>상품설명</td>
<td><textarea rows="5" cols="60" name="productDesc" id="productDesc"></textarea></td>
</tr>
<tr>
<td>상품이미지</td>
<td><input type="file" name="productPhoto" id="productPhoto"></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="button" value="등록" id="addBtn">
<input type="button" value="목록" id="listBtn">
</td>
</tr>
</table>
</form>
<form id="form1" name="form1" enctype="multipart/form-data" method="post">
enctype="multipart/form-data" method="post"
: 이미지파일 업로드하기 위한form
태그 속성
2) 상품목록 페이지 (productList.jsp)
구현화면 - 권한에 따라 상품목록의 차이점 구분
일반 사용자 상품목록
관리자 상품목록
상품목록 페이지 Javascript 코드
$(document).ready(function(){
$("#btnAdd").click(function(){
location.href="${path}/shop/product/write.do";
});
});
상품등록 버튼 클릭이벤트가 발생하면 상품등록페이지로 이동
상품목록 페이지 HTML 코드
<h2>상품목록</h2>
<c:if test="${sessionScope.adminId != null}">
<button type="button" id="btnAdd">상품등록</button><br>
</c:if>
<table border="1">
<tr>
<th>상품ID</th>
<th>상품이미지</th>
<th>상품명</th>
<th>가격</th>
</tr>
<c:forEach var="row" items="${list}">
<tr>
<td>
${row.productId}
</td>
<td>
<a href="${path}/shop/product/detail/${row.productId}">
<img src="${path}/images/${row.productUrl}" width="120ox" height="110px">
</a>
</td>
<td align="center">
<a href="${path}/shop/product/detail/${row.productId}">${row.productName}</a><br>
<c:if test="${sessionScope.adminId != null}">
<a href="${path}/shop/product/edit/${row.productId}">[상품편집]</a>
</c:if>
</td>
<td>
<fmt:formatNumber value="${row.productPrice}" pattern="###,###,###"/>
</td>
</tr>
</c:forEach>
</table>
<c:if test="${sessionScope.adminId != null}">상품등록 버튼</c:if>
- session에 저장된id가 관리자id이면 상품등록 버튼 출력
<c:if test="${sessionScope.adminId != null}">상품편집 링크</c:if>
- session에 저장된id가 관리자id이면 상품편집 링크 출력
2) 상품수정, 삭제 페이지 (productEdit.jsp)
구현화면
상품수정, 삭제페이지 Javascript 코드
$(document).ready(function(){
// 상품 수정 버튼 클릭이벤트
$("#editBtn").click(function(){
var productName = $("#productName").val();
var productPrice = $("#productPrice").val();
var productDesc = $("#productDesc").val();
// 상품 수정 폼 유효성 검사
if(productName == "") {
alert("상품명을 입력해주세요");
productName.foucs();
} else if (productPrice == "") {
alert("상품 가격을 입력해주세요");
productPrice.focus();
} else if (productDesc == "") {
alert("상품 설명을 입력해주세요");
productDesc.focus();
}
document.form1.action = "${path}/shop/product/update.do";
document.form1.submit();
});
// 상품 삭제 버튼 클릭이벤트
$("#deleteBtn").click(function(){
// 상품 삭제 확인
if(confirm("상품을 삭제하시겠습니까?")){
document.form1.action = "${path}/shop/product/delete.do";
document.form1.submit();
}
});
// 상품 목록 버튼 클리이벤트
$("#listBtn").click(function(){
location.href = "${path}/shop/product/list.do";
});
});
상품 수정버튼 클릭이벤트가 발생하면 유효성 검사후 업데이트 처리
상품 삭제버튼 클릭이벤트가 발생하면confirm()
함수를 이용하여 삭제확인을 한 뒤 삭제처리
상품 목록버튼 클릭이벤트가 발생하면 상품 목록 페이지로 이동
상품수정, 삭제페이지 HTML 코드
<h2>상품 정보/삭제</h2>
<form id="form1" name="form1" enctype="multipart/form-data" method="post">
<table border="">
<tr>
<td>상품 이미지</td>
<td>
<img src="${path}/images/${vo.productUrl}" height="300px" width="310px">
<br>
<input type="file" id="productPhoto" name="productPhoto">
</td>
</tr>
<tr>
<td>상품명</td>
<td><input type="text" id="productName" name="productName" value="${vo.productName}"></td>
</tr>
<tr>
<td>가격</td>
<td><input type="number" id="productPrice" name="productPrice" value="${vo.productPrice}"></td>
</tr>
<tr>
<td>상품소개</td>
<td><textarea id="productDesc" name="productDesc" rows="5" cols="60">${vo.productDesc}</textarea></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="hidden" name="productId" value="${vo.productId}">
<input type="button" id="editBtn" value="수정">
<input type="button" id="deleteBtn"value="삭제">
<input type="button" id="listBtn" value="상품목록">
</td>
</tr>
</table>
</form>
<form id="form1" name="form1" enctype="multipart/form-data" method="post">상품업데이트</form>
enctype="multipart/form-data" method="post"
: 이미지파일 업로드하기 위한form
태그 속성
<input type="file" id="productPhoto" name="productPhoto">
: 이미지파일 업로드 태그
2. Controller(흐름제어)
상품관련 컨트롤러(ProductCotroller)
@Controller
@RequestMapping("shop/product/*")
public class ProductController {
@Inject
ProductService productService;
// 1. 상품 전체 목록 - 코드 생략....
// 2. 상품 상세보기 - 코드 생략....
// 3. 상품등록 페이지 매핑
@RequestMapping("write.do")
public String write(){
return "/shop/productWrite";
}
// 4. 상품등록 처리 매핑
@RequestMapping("insert.do")
public String insert(ProductVO vo){
String filename = "";
// 첨부파일(상품사진)이 있으면
if(!vo.getProductPhoto().isEmpty()){
filename = vo.getProductPhoto().getOriginalFilename();
// 개발디렉토리 - 파일 업로드 경로
//String path = "C:\\Users\\doubles\\Desktop\\workspace\\gitSpring\\"
// + "spring02\\src\\main\\webapp\\WEB-INF\\views\\images";
// 배포디렉토리 - 파일 업로드 경로
String path = "C:\\Users\\doubles\\Desktop\\workspace\\spring\\"
+ "\\.metadata\\.plugins\\org.eclipse.wst.server.core\\"
+ "tmp0\\wtpwebapps\\spring02\\WEB-INF\\views\\images\\";
try {
new File(path).mkdirs(); // 디렉토리 생성
// 임시디렉토리(서버)에 저장된 파일을 지정된 디렉토리로 전송
vo.getProductPhoto().transferTo(new File(path+filename));
} catch (Exception e) {
e.printStackTrace();
}
vo.setProductUrl(filename);
productService.insertProduct(vo);
}
return "redirect:/shop/product/list.do";
}
// 5. 상품 수정(편집) 페이지 매핑
@RequestMapping("edit/{productId}")
public ModelAndView edit(@PathVariable("productId") int productId, ModelAndView mav){
mav.setViewName("/shop/productEdit");
mav.addObject("vo", productService.detailProduct(productId));
return mav;
}
// 6. 상품 수정(편집) 처리 매핑
@RequestMapping("update.do")
public String update(ProductVO vo){
String filename = "";
// 첨부파일(상품사진)이 변경되면
if(!vo.getProductPhoto().isEmpty()){
filename = vo.getProductPhoto().getOriginalFilename();
// 개발디렉토리 - 파일 업로드 경로
//String path = "C:\\Users\\doubles\\Desktop\\workspace\\gitSpring\\"
// + "spring02\\src\\main\\webapp\\WEB-INF\\views\\images";
// 배포디렉토리 - 파일 업로드 경로
String path = "C:\\Users\\doubles\\Desktop\\workspace\\spring\\"
+ "\\.metadata\\.plugins\\org.eclipse.wst.server.core\\"
+ "tmp0\\wtpwebapps\\spring02\\WEB-INF\\views\\images\\";
try {
new File(path).mkdirs(); // 디렉토리 생성
// 임시디렉토리(서버)에 저장된 파일을 지정된 디렉토리로 전송
vo.getProductPhoto().transferTo(new File(path+filename));
} catch (Exception e) {
e.printStackTrace();
}
vo.setProductUrl(filename);
// 첨부파일이 변경되지 않으면
} else {
// 기존의 파일명
ProductVO vo2 = productService.detailProduct(vo.getProductId());
vo.setProductUrl(vo2.getProductUrl());
}
productService.updateProduct(vo);
return "redirect:/shop/product/list.do";
}
// 7. 상품 삭제 처리 매핑
@RequestMapping("delete.do")
public String delete(@RequestParam int productId){
// 상품 이미지 정보
String filename = productService.fileInfo(productId);
String path = "C:\\Users\\doubles\\Desktop\\workspace\\spring\\"
+ "\\.metadata\\.plugins\\org.eclipse.wst.server.core\\"
+ "tmp0\\wtpwebapps\\spring02\\WEB-INF\\views\\images\\";
// 상품 이미지 삭제
if(filename != null){
File file = new File(path+filename);
// 파일이 존재하면
if (file.exists()){
file.delete(); // 파일 삭제
}
}
// 레코드 삭제
productService.deleteProduct(productId);
return "redirect:/shop/product/list.do";
}
}
@RequestMapping("write.do")
: 상품등록 페이지 매핑
@RequestMapping("insert.do")
: 상품등록 처리 매핑
new File(path).mkdirs();
: 이미지파일을 저장할 디렉토리 생성
vo.getProductPhoto().transferTo(new File(path+filename));
:path
디렉토리,filenmae
원본이미지파일명, 서버에 임시 저잗된 파일을 저장디렉토리로 전송
return "redirect:/shop/product/list.do";
상품등록 처리후 목록페이지로 리다이렉트
@RequestMapping("edit/{productId}")
: 상품 편집 페이지 매핑
- 상품편집페이지와 상품정보를 ModelAndView를 이용하여 리턴
@RequestMapping("update.do")
: 상품 편집 처리 매핑
- 상품 이미지 파일을 변경할 경우, 상품등록시 이미지파일을 업로드 한경우와 동일하게 처리
- 상품 이지미 파일을 변경하지 않을 경우, 기존의 파일명을 가져와서 처리
return "redirect:/shop/product/list.do";
: 상품목록페이지로 리다이렉트
@RequestMapping("delete.do")
: 상품 삭제 처리 매핑
- 상품이미지정보를 조회한 뒤 상품이미지와 DB레코드를 함께 삭제처리
3. Service(비지니스로직, DB연동 이외의 핵심업무 처리)
상품관련 Service (ProductServiceImpl)
@Service
public class ProductServiceImpl implements ProductService {
@Inject
ProductDAO productDao;
// 01. 상품목록 - 코드생략....
// 02. 상품상세 - 코드생략....
// 03. 상품추가
@Override
public void insertProduct(ProductVO vo) {
productDao.insertProduct(vo);
}
// 04. 상품수정
@Override
public void updateProduct(ProductVO vo) {
productDao.updateProduct(vo);
}
// 05. 상품삭제
@Override
public void deleteProduct(int productId) {
productDao.deleteProduct(productId);
}
// 06. 상품이미지 삭제를 위한 이미지파일 정보
@Override
public String fileInfo(int productId) {
return productDao.fileInfo(productId);
}
}
insertProduct(ProductVO vo)
: 상품 추가/입력 처리를 위해 상품관련DAO의insertProduct()
메서드 호출updateProduct(ProductVO vo)
: 상품 수정처리를 위해 상품관련DAO의updateProduct()
메서드 호출deleteProduct(int productId)
: 상품 삭제처리를 위해 상품관련DAO의deleteProduct()
메서드 호출fileInfo(int productId)
: 상품이미지 파일 삭제처리를 위해 상품관련DAO의fileInfo()
메서드
4. DAO(비지니스로직, DB연동작업처리)
상품관련 DAO (ProductDAOImpl)
@Repository
public class ProductDAOImpl implements ProductDAO {
@Inject
SqlSession sqlSession;
// 01. 상품목록 - 코드생략....
// 02. 상품상세 - 코드생략....
// 03. 상품추가
@Override
public void insertProduct(ProductVO vo) {
sqlSession.insert("product.insertProduct", vo);
}
// 04. 상품수정
@Override
public void updateProduct(ProductVO vo) {
sqlSession.update("product.updateProduct", vo);
}
// 05. 상품삭제
@Override
public void deleteProduct(int productId) {
sqlSession.delete("product.deleteProduct", productId);
}
// 06. 상품이미지 삭제를 위한 이미지파일 정보
@Override
public String fileInfo(int productId) {
return sqlSession.selectOne("product.fileInfo",productId);
}
}
insertProduct(ProductVO vo)
: 상품정보 insertupdateProduct(ProductVO vo)
: 상품정보 updatedeleteProduct(int productId
: 상품정보 deletefileInfo(int productId)
: 상품이미지 삭제를 위한 이미지파일 정보를 select조회한 결과를 리턴
5. MybatisMapper(SQL문)
상품관련 Mapper (productMapper.xml)
<mapper namespace="product">
<!-- 01. 상품 전체 리스트 -->
<!-- 02. 상품 상세보기 -->
<!-- 코드생략... -->
<!-- 03. 상품 추가하기 -->
<insert id="insertProduct">
INSERT INTO tbl_product
VALUES (
seq_product.NEXTVAL
, #{productName}
, #{productPrice}
, #{productDesc}
, #{productUrl}
)
</insert>
<!-- 04. 상품 수정/편집하기 -->
<update id="updateProduct">
UPDATE tbl_product
SET product_name = #{productName}
, product_price = #{productPrice}
, product_desc = #{productDesc}
, product_url = #{productUrl}
WHERE
product_id = #{productId}
</update>
<!-- 05. 상품 레코드 삭제처리 -->
<delete id="deleteProduct">
DELETE FROM tbl_product
WHERE product_id = #{productId}
</delete>
<!-- 06. 삭제를 위한 상품 이미지 파일이름 select -->
<select id="fileInfo" resultType="String">
SELECT product_url AS productUrl
FROM tbl_product
WHERE product_id = #{productId}
</select>
</mapper>
insertProduct
: 상품 추가를 위해 insert sqlupdateProduct
: 상품 수정/편집을 위해 update sqldeleteProduct
: 상품 레코드 삭제를 위한 delete sqlfileInfo
: 상품 이미지파일 삭제를 위한 이미지파일명 select sql