지난시간에 이어 이번에는 게시글 수정기능을 한번 추가해보도록 하겠다.
bordselectone1.jsp
<body>
<a href="updateone.do?no=${brd.no}"><input type="button" value="수정" /></a>
jsp의 경우에는 수정버튼에 <a>
태그를 추가하여 게시글 no
가 updateone.do
의 주소지로 들어가도록 구성했다. 해당 주소를 가지는 servlet을 만들어주었다.
package controller;
import java.io.IOException;
import config.MyBatisContext;
import dto.Board;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import mapper.BoardMapper;
@WebServlet(urlPatterns = { "/board/updateone.do" })
public class BoardUpdateServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
BoardMapper mapper = MyBatisContext.getSqlSession().getMapper(BoardMapper.class);
public BoardUpdateServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
BoardMapper mapper = MyBatisContext.getSqlSession().getMapper(BoardMapper.class);
// ex) ?no=XX
long no = Long.parseLong(request.getParameter("no"));
Board board = mapper.selectBoardOne(no);
// view로 값 전달
request.setAttribute("obj", board);
// view 표시
request.getRequestDispatcher("/WEB-INF/boardupdateone1.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 전송되는 4개의 데이터를 받음
long no = Long.parseLong(request.getParameter("no")); // view의 name값과 매칭
String title = request.getParameter("title");
String writer = request.getParameter("writer");
String content = request.getParameter("content");
// 여기는 데이터의 변경(추가, 수정, 삭제)를 수행하고
Board board = new Board();
board.setTitle(title);
board.setContent(content);
board.setWriter(writer);
board.setNo(no);
int ret = mapper.updateBoardOne(board);
// <a>태그의 기능을 이용해서 페이지를 바꿈.
if(ret == 1) {
response.sendRedirect("selectone.do?no=" + no); // 성공
}
else {
response.sendRedirect("updateone.do?no=" + no); // 실패
}
}
// 이외에도 doDelete, doPut, doPatch 등등의 메소드가 존재한다.
/*
* doGet : 조회
* doPost : 추가
* doDelete : 삭제
* doPut : 수정
* doPatch : 일부수정
*/
}
이후 변경된 데이터fmf Board로 묶어준 뒤, Mapper를 통해서 전송한다.
이때, 전송이 올바르다면 게시글화면으로, 실패한다면 수정화면으로 되돌아가게 된다.
이번에는 판매 기능을 추가해보려고 한다.
위의 기능을 순차적으로 구현하고자 한다. 오늘은 이미지1개 등록 페이지까지 구현을 마친 상태이다.
먼저 테이블부터 생성해주도록 하자.
CREATE SEQUENCE SEQ_ITEM_NO
INCREMENT BY 1
START WITH 1001;
CREATE SEQUENCE SEQ_ITEMIMAGE_NO
INCREMENT BY 1
START WITH 10001;
-- ------------------------------------------------------------------------
CREATE TABLE ITEM(
no NUMBER default seq_item_no.nextval,
name varchar2(100),
content clob,
price NUMBER,
quantity NUMBER,
regdate TIMESTAMP default CURRENT_TIMESTAMP,
CONSTRAINT item_pk PRIMARY KEY(no)
);
CREATE TABLE ITEMIMAGE(
no NUMBER default seq_itemimage_no.nextval,
filename varchar2(200),
filedata blob,
filetype varchar2(50),
filesize NUMBER,
itemno NUMBER,
regdate TIMESTAMP default CURRENT_TIMESTAMP,
CONSTRAINT itemimage_pk PRIMARY KEY(no),
CONSTRAINT itemimage_fk FOREIGN KEY(itemno) REFERENCES item(no)
);
-- ------------------------------------------------------------------------
다음으로는 dto를 만들어주도록 하겠다.
package dto;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Item {
private long no;
private String name;
private String content;
private long quantity;
private long price;
private Date regdate;
}
package dto;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString (exclude = {"filedata"})
@NoArgsConstructor
@AllArgsConstructor
public class ItemImage {
private long no;
private String filename;
private long filesize;
private byte[] filedata; //BLOB
private String filetype;
private long itemno;
private Date regdate;
}
package mapper;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import dto.Item;
@Mapper
public interface ItemMapper {
/*------------------------------------------------------------------------------------------------------*/
@Insert( value = {
" INSERT INTO item( name, content, price, quantity ) ",
" VALUES (",
" #{obj.name}, #{obj.content}, ",
" #{obj.price}, #{obj.quantity} ) "
} )
public int insertItemOne(@Param("obj") Item item); // 물품 추가
/*------------------------------------------------------------------------------------------------------*/
// #{} => 값을 표현할 때
// ${} => 컬럼명, 테이블명 등..
@Select( value = {
" SELECT * FROM item ",
" WHERE ${column} ",
" LIKE '%' || #{text} || '%' ",
" ORDER BY no DESC "
} )
public List<Item> selectItemList(@Param("column") String column,@Param("text") String text ); // 물품정보 조회 (목록창 + 검색기능)
/*------------------------------------------------------------------------------------------------------*/
@Select( value = {
" SELECT ",
" COUNT(*) ",
" FROM item "
} )
public long countItemList(); // 전체물품 조회
/*------------------------------------------------------------------------------------------------------*/
}
package mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import dto.ItemImage;
@Mapper
public interface ItemImageMapper {
@Insert( value = {
" INSERT INTO itemimage ( itemno, filename, filesize, filetype, filedata ) ",
" VALUES ( ",
" #{obj.itemno}, #{obj.filename}, ",
" #{obj.filesize}, #{obj.filetype}, ",
" #{obj.filedata} ) "
} )
public int insertItemImage(@Param("obj") ItemImage itemImage); // 물품이미지 추가
}
까먹지 말고 항상 Mapper를 만든 후 MyBatis에 등록을 해주도록 하자. (ItemImageMapper도!)
package controller;
import java.io.IOException;
import config.MyBatisContext;
import dto.Item;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import mapper.ItemMapper;
@WebServlet(urlPatterns = { "/seller/insertone.do" }) // 원래라면 이렇게 구성해주어야 함!
public class ItemInsertServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
ItemMapper mapper = MyBatisContext.getSqlSession().getMapper(ItemMapper.class);
public ItemInsertServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("title", "물품1개등록");
request.getRequestDispatcher("/WEB-INF/iteminsert1.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 전달된값 받기 (4개)
// int ret = mapper를 이용해서 추가수행
Item obj = new Item();
obj.setName(request.getParameter("name"));
obj.setContent(request.getParameter("content"));
obj.setPrice(Long.parseLong(request.getParameter("price")));
obj.setQuantity(Long.parseLong(request.getParameter("quantity")));
int ret = mapper.insertItemOne(obj);
if (ret == 1) {
response.sendRedirect("selectlist.do");
} else {
response.sendRedirect("insertimageone.do");
}
}
}
package controller;
import java.io.IOException;
import java.util.List;
import config.MyBatisContext;
import dto.Item;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import mapper.ItemMapper;
@WebServlet(urlPatterns = { "/seller/selectlist.do" }) // 원래라면 이렇게 구성해주어야 함!
public class ItemSelectServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ItemSelectServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ItemMapper mapper = MyBatisContext.getSqlSession().getMapper(ItemMapper.class);
// 서버주소/seller/selectlist.do
// 서버주소/seller/selectlist.do /type=name&text=~~~~
String type = request.getParameter("type");
String text = request.getParameter("text");
if(type == null) {
type ="name";
}
if(text == null) {
text = "";
}
// 1. 검색하고자 하는 컬럼의 종류, 내용
List<Item> list = mapper.selectItemList(type, text);
// 2. view로 전달 할 값
request.setAttribute("list", list);
// 3. 사용하고자 하는 view
request.getRequestDispatcher("/WEB-INF/itemselectlist1.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
package controller;
import java.io.IOException;
import config.MyBatisContext;
import dto.ItemImage;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
import mapper.ItemImageMapper;
@WebServlet(urlPatterns = { "/seller/insertimageone.do" }) // 원래라면 이렇게 구성해주어야 함!
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 1, // M
maxFileSize = 1024 * 1024 * 10, // 10M
maxRequestSize = 1024 * 1024 * 100 // 100M
)
public class ItemInsertImageServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ItemInsertImageServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// /seller/insertimageone.do?itemno=1004
long no = Long.parseLong(request.getParameter("itemno"));
request.setAttribute("itemno", no);
request.setAttribute("title", "물품이미지1개 등록");
request.getRequestDispatcher("/WEB-INF/itemimageinsert1.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ItemImageMapper mapper = MyBatisContext.getSqlSession().getMapper(ItemImageMapper.class);
long itemno = Long.parseLong(request.getParameter("itemno"));
Part part = request.getPart("file");
ItemImage obj = new ItemImage(); // 이미지 저장 dto
obj.setItemno(itemno);
obj.setFilename( part.getSubmittedFileName() ); // 첨부한 파일명
obj.setFilesize( part.getSize() ); // 첨부한 파일크기
obj.setFiletype( part.getContentType() ); // 첨부한 파일의 종류 (gif, jpg, png ...)
obj.setFiledata( part.getInputStream().readAllBytes() ); // 첨부한 파일 실제 데이터
int ret = mapper.insertItemImage(obj);
if(ret == 1 ) {
response.sendRedirect("selectlist.do");
}
else {
response.sendRedirect("insertimageone.do?itemno="+ itemno); // 실패시 현재페이지로
}
// mapper를 만들어서 insert를 수행하면 DB에 추가가 됨.
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri ="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>물품등록하기</title>
</head>
<body>
<h3>${title}</h3>
<form action = "insertone.do" method="post">
물품명 : <input type="text" name="name"/><br />
물품설명 : <textarea rows="6" name="content"/></textarea><br />
가격 : <input type="number" name="price"/><br />
수량 : <input type="number" name="quantity"/><br />
<input type="submit" value="등록하기"/>
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri ="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>물품목록</title>
</head>
<body>
<form action="selectlist.do" method="get">
<select name="type">
<option value="name">물품명</option>
<option value="content">물품내용</option>
</select>
<input type="text" name="text" placeholder="검색어 입력" />
<input type="submit" value="검색" />
</form>
<hr />
<c:forEach var="obj" items="${list}">
${obj.no}, ${obj.name}, ${obj.content},
${obj.price}, ${obj.quantity}, ${obj.regdate}
<button>물품1개수정</button>
<button>물품1개삭제</button>
<a href="insertimageone.do?itemno=${obj.no}"><button>이미지1개등록</button></a>
<br />
</c:forEach>
<hr />
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>${title}</title>
</head>
<body>
<h3>${title}</h3>
<!-- 주소창을 바꾸고 정보는 숨기고, 정보의 내용중에서는 파일도 있음. -->
<form action="insertimageone.do" method="post" enctype="multipart/form-data">
물품번호 1.(주소창의 값을 바로읽기) : <input type="text" value="${param.itemno}" readonly/><br />
물품번호 2.(Servlet에서 받아오기)) : <input type="text" value="${itemno}" name="itemno" readonly/><br />
이미지 : <input type="file" name="file" /><br />
<input type="submit" value="이미지등록" />
</form>
</body>
</html>
오늘은 JSP와 Servlet의 코드를 구성하면서 상관관계를 이해하느라 많은 시간을 소모했다.
빠른시일내에 HTML을 학습하여 부지런히 쫓아가도록 해야겠다.