2일차. 오라클에서 시퀀스와 테이블을 만들고 시작하자!
좌측 시퀀스 우클릭 후 생성을 누르자
이렇게 작성 후 확인을 누르면 시퀀스가 생성된다.
이번엔 테이블을 만들어보자
새 테이블을 누르면
이런 창이 뜰 것이다. 우측 + 버튼을 눌러 항목들을 추가하고
이렇게 작성하여 테이블을 만들자.
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 = {"regdate"})
@NoArgsConstructor
@AllArgsConstructor
public class Board {
private long no;
private String title;
private String content;
private String writer;
private long hit;
private Date regdate;
}
우선 만튼 테이블을 토대로 위 코드처럼 dto에 Board.java를 만들자
Java mapper에 BoardMapper.java를 생성하고
@Insert({
" Insert Into board (title, content, writer)",
" VALUES(#{obj.title}, #{obj.content}, #{obj.writer}) "
})
public int InsertBoardOne(@Param("obj")Board obj);
위 코드도 추가하자.
config.addMapper(BoardMapper.class);
Java - config - MybatisContext.java에 BoardMapper추가
이제 test를 해보자
web01을 우클릭하여 Properties로 들어가보자
위 사진처럼 Libraries - Add Library를 눌러
JUnit5를 선택하여 Finish를 눌러 JUnit 5을 생성하자.
Java Resources 하위폴더인 src/test/java - web01 패키지에
위 방식처럼 BoardTest를 생성하자.
BoardMapper mapper = MyBatisContext.getSqlSession().getMapper(BoardMapper.class);
BoardTest에 추가하고
@Test
void insertBoardOne() {
Board obj = new Board();
obj.setTitle("제목");
obj.setContent("내용임");
obj.setWriter("작성자임");
int ret = mapper.InsertBoardOne(obj);
System.out.println(ret);
}
BoardTest 실행.
성공하면 이렇게 하나가 추가된다.
Servlet을 선택하고 next를 누르고
/board/insert.do로 변경하여 생성한다.
@WebServlet(urlPatterns = {"/board/selectlist.do"})
public class BoardSelectServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
방금 생성한 BoardInsertServlet 맨 위에 urlPatterns 작성한다.
Server Start해서 확인해보자. (뒤에 다른 수업 따라가면서 하다보니 결과화면 캡쳐를 못했다 ㅠㅠ)
WEB-INF에 web.xml에 servlet삭제 ( welcome-file-list ~ web-app 사이에 있는 거 모두 삭제)
BoardInsertServlet 작성 후 boardinsert1.jsp 접속하여 위 사진처럼
404 오류에 boardinsert1.jsp 없다는 문구가 뜨면 정상
<%@ 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>
</head>
<body>
<a href="insertone.do">글쓰기로 이동</a>
<hr />
<c:forEach var="obj" items="${list}">
${obj.no}, <a href="selectone.do?no=${obj.no}">${obj.title}</a>, ${obj.writer}, ${obj.hit}, ${obj.regdate} <br />
</c:forEach>
<hr />
<c:forEach var="i" begin="1" end="${pages}">
<a href="selectlist.do?page=${i}">${i}</a>
</c:forEach>
</body>
</html>
WEB-INF에 JSP File로 boardinsert1.jsp 생성 후 title, body를 작성하고
board/insertone.do 접속해서 위 사진처럼 나온다면 성공.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 사용자가 입력한 항목 3개를 받아서 db에 추가하고
// 페이지로 이동시켜야함 (절대로 post로 보내면 안됨, get으로만 보냄)
String title = request.getParameter("title");
String content = request.getParameter("content");
String writer = request.getParameter("writer");
Board obj = new Board();
obj.setTitle(title);
obj.setContent(content);
obj.setWriter(writer);
System.out.println(obj.toString());
int ret = mapper.InsertBoardOne(obj); //4번
if(ret ==1) {//글쓰기 성공 => 게시판 목록
// 주소창을 selectlist.do로 변경시키고 엔터키를 누름
response.sendRedirect("selectlist.do");
}
else {//글쓰기 실패 => 다시 글쓰기 화면으로 이동
// 주소창을 insertone.do로 변경시키고 엔터키를 자동화 GET
response.sendRedirect("insertone.do");
}
}
BoardInsertServlet.jsp에 doPost에 String title, content, writer 작성하고
BoardMapper mapper = MyBatisContext.getSqlSession().getMapper(BoardMapper.class);
위 코드를 public BoardInsertServlet 위에 추가하여 Mybatis와 연동한다.
Board obj = new Board();
obj.setTitle(title);
obj.setContent(content);
obj.setWriter(writer);
System.out.println(obj.toString());
int ret = mapper.InsertBoardOne(obj); //4번
if(ret ==1) {//글쓰기 성공 => 게시판 목록
// 주소창을 selectlist.do로 변경시키고 엔터키를 누름
response.sendRedirect("selectlist.do");
}
else {//글쓰기 실패 => 다시 글쓰기 화면으로 이동
// 주소창을 insertone.do로 변경시키고 엔터키를 자동화 GET
response.sendRedirect("insertone.do");
}
String 아래에 위 코드를 다 추가한다.
여티 Servlet 파일을 만들었던 것처럼 BoardSelectServlet.jsp을 만들고 web.xml에서 삭제할 부분을 삭제하자.
BoardSelectServlet.jsp에
@WebServlet(urlPatterns = {"/board/selectlist.do"})
request.getRequestDispatcher("/WEB-INF/boardselectlist1.jsp").forward(request, response);
맨 위에 @WebServlet, doGet에 위 코드를 각각 작성한다.
WEB-INF에 JSP File로 boardselectlist1.jsp 생성하고
@Select({
" SELECT b.* FROM( select b.*, ROW_NUMBER() OVER(ORDER BY no DESC) rown FROM board b) ",
" b WHERE rown >= #{start} AND rown<=#{end} "
})
public List<Board> selectBoardList(@Param("start") int start, @Param("end") int end);
BoardMapper에 sql문을 이용하여 작성하고
// 1. mapper를 통해서 결과값 가져오기
List<Board> list = mapper.selectBoardList(10*page-9, 10*page);
long total = mapper.countBoardList();
// 36 => 4
// 30 => 3
// 2. view로 값전달
request.setAttribute("pages", ( total-1 )/10 + 1 );
request.setAttribute("list", list);
BoardSelectServlet에 돌아와서 doGet에 위 코드들을 작성해준다.
<%@ 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>
</head>
<body>
<a href="insertone.do">글쓰기로 이동</a>
<hr />
<c:forEach var="obj" items="${list}">
${obj.no}, <a href="selectone.do?no=${obj.no}">${obj.title}</a>, ${obj.writer}, ${obj.hit}, ${obj.regdate} <br />
</c:forEach>
<hr />
<c:forEach var="i" begin="1" end="${pages}">
<a href="selectlist.do?page=${i}">${i}</a>
</c:forEach>
</body>
</html>
boardselectlist1.jsp 또한 위처럼 작성한다.
아래에 페이지 기능을 만들어보자.
@Select({
" SELECT b.* FROM board b WHERE NO =#{no} "
})
public Board selectBoardOne(@Param("no") long no);
우선 BoardMapper에 위 sql문을 추가하자.
long total = mapper.countBoardList();
request.setAttribute("pages", ( total-1 )/10 + 1 );
BoardSelectServlet에도 위 코드를 추가하자.
<c:forEach var="i" begin="1" end="${pages}">
${i}
</c:forEach>
boardselectlist1.jsp에 위 코드를 작성하자.
오라클 서버가 자꾸 튕기기 시작했다.
다른 방안을 찾아야 한다..
http://1.234.5.158:30081/login.jsp 임베디드 h2 (pl sql 사용 불가)를 사용하자
위 사진처럼 임베디드 h2에서 똑같이 시퀀스, 테이블 생성했다.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
<scope>runtime</scope>
</dependency>
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:tcp://1.234.5.158:31521/ds201;Mode=Oracle");
dataSource.setUsername("sa");
dataSource.setPassword("");
<c:forEach var="i" begin="1" end="${pages}">
<a href="selectlist.do?page=${i}">${i}</a>
</c:forEach>
boardselectlist1.jsp 에서 위 코드를 추가하게 되면
아래 페이지를 누르면 url이 바뀌는 걸 확인할 수 있다.
BoardSelectServlet에
int page =1;
if(request.getParameter("page") != null) {
// get에는 ?page=1일 경우 1의 값을 읽는 방법
page = Integer.parseInt( request.getParameter("page"));
를 추가,
List<Board> list = mapper.selectBoardList(10*page-9, 10*page);
으로 수정한 뒤
페이지 바꾸면 몫도 같이 바뀌는 걸 확인.
BoardSelectServlet 생성 후 web.xml 내용 삭제하자.
@WebServlet(urlPatterns = {"/board/selectone.do"})
public class BoardSelectOneServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public BoardSelectOneServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BoardMapper mapper = MyBatisContext.getSqlSession().getMapper(BoardMapper.class);
Long no = Long.parseLong(request.getParameter("no"));
// 1.mapper를 이용하여 게시글 1개 가져오기
Board board = mapper.selectBoardOne(no);
// 2. view로 전송
request.setAttribute("brd", board);
// 3. view 표시
request.getRequestDispatcher("/WEB-INF/boardselectone1.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
BoardSelectServlet에 위 코드를 작성하고
<meta charset="UTF-8">
<title>게시글조회</title>
</head>
<body>
글번호 : ${brd.no} <br />
글제목 : ${brd.title} <br />
글내용 : ${brd.context} <br />
작성자 : ${brd.writer} <br />
조회수 : ${brd.hit} <br />
날짜 : ${brd.regdate} <br />
<hr />
<a href="selectlist.do"><intput type="button" value="목록" /></a>
<input type="button" value="수정" />
<input type="button" value="삭제" />
<input type="button" value="이전글" />
<input type="button" value="다음글" />
</body>
WEB-INF에 boardselectone1.jsp 생성 후 위 코드를 작성하자.
@Select({
" SELECT b.* FROM board b WHERE NO =#{no} "
})
public Board selectBoardOne(@Param("no") long no);
그리고 Mapper에 추가하자.
이전글, 다음글, 삭제기능을 추가해보자
우선 mapper에 다음을 추가하자.
@Select({
" SELECT NVL(MIN(no),0) FROM board WHERE no > #{no}"
})
public long selectBoardNext(@Param("no") long no);
@Select({
" SELECT NVL(MIN(no),0) FROM board WHERE no < #{no}"
})
public long selectBoardPrev(@Param("no") long no);
@Delete({
" DELETE board WHERE no=#{no} "
})
public int deleteBoardOne(long no);
이젠 BoardSelectOneServlet으로 가보자.
long next = mapper.selectBoardNext(no);
long prev = mapper.selectBoardNext(no);
request.setAttribute("next", next);
request.setAttribute("prev", prev);
위 코드를 추가하자!
@WebServlet(urlPatterns = {"/board/deleteone.do"})
public class BoardDeleteOneServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
BoardMapper mapper = MyBatisContext.getSqlSession().getMapper(BoardMapper.class);
public BoardDeleteOneServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Long no = Long.parseLong(request.getParameter("no"));
int board = mapper.deleteBoardOne(no);
request.setAttribute("brd.no", board);
if(board == 1) {
response.sendRedirect("selectlist.do");
}
}
BoardSelectOneServlet을 만들어서 위 코드를 넣자.
<h3>게시글조회</h3>
<hr />
글번호 : ${brd.no} <br />
글제목 : ${brd.title} <br />
글내용 : ${brd.content} <br />
작성자 : ${brd.writer} <br />
조회수 : ${brd.hit} <br />
날짜 : ${brd.regdate} <br />
<hr />
<a href="selectlist.do"><intput type="button" value="목록" /></a>
<input type="button" value="수정" />
<form action="deleteone.do" method="post" style="display:inline-block;">
<input type="text" name="no" value="${brd.no}" />
<input type="submit" value="삭제" />
</form>
<c:if test="${prev > 0}">
<a href="selectone.do?no=${prev}"><input type="button" value="이전글" /></a>
</c:if>
<c:if test="${next >0}">
<a href="selectone.do?no=${next}"><input type="button" value="다음글" /></a>
</c:if>
마지막으로 boardselectone1.jsp의 body에 위 코드를 작성하고 실행시켜보자.
20을 기준으로 다음글을 누르면
21로 바뀐 모습을 볼 수 있다.
반대로 이전글을 누르게되면
다시 20으로 갈 수 있다.
여기서 삭제버튼을 누르면 selectlist.do로 이동하면서
20이 사라진 모습을 볼 수 있다.
여기까지 오늘 배운 내용을 정리해보았다.
중간에 놓친 부분도 많아서 제대로 정리하진 못했다. 추후에 수정 및 추가할 수 있도록 해야겠다.