학습목표
게시판 등록, 조회를 구현할 수 있다.
JDBC PreparedStatement에 대해 설명할 수 있다.
게시판 등록. 조회
Statement
- JDBC 작성은 데이터베이스에서 원하는 SQL 문을 실행시켜 결과 값을 얻기 위함
- 실제 데이터베이스에서 SQL문이 함수를 call 하는 시점에 매개 변수로 SQL 문을 지정함
- SQL을 실행시키는 API
- 객체 생성 시점에 SQL 문을 지정하지 않음
conn.createStatement();
SQL 문을 실행 메소드의 인자로 줌
- st.execute(sql) : 수행결과가 ResultSet이면 true, 아니면 false 리턴
- st.executeQuery(sql) : Select문 수행결과를 ResultSet에 담아서 리턴함
- st.executeUpdate(sql) : Row 수를 리턴, Insert / Update / Delete문 수행 시 사용
rs = st.executeQuery(sql);
PreparedStatement
- Statement interface를 상속한 interfacce
- SQL 문은 동일하고 변수의 값만 다른 경우에 사용하면 효율적임 (데이터만 바꿔야할 때)
- SQL 문을 어디서 지정하느냐 차이가 있음
- Connection의 prepareStatement() 함수로 객체 획득
- 객체 획득 시점에 SQL문 지정
conn.prepareStatement(sql);
- SQL 문에 데이터 부분을 ?로 처리
- ?는 이후 지정되는 데이터를 의미함
- SQL 문의 포맷을 미리 준비해놓고 실행 시 데이터 변경만 하여 계속 동일한 구조의 SQL 문 실행
update board set title=?, content=? where seq=?
- SQL문 실행 전에 setXxx()로 ?에 데이터 바인딩
ps.setInt(1, 1036);
ps.setString(2, "test");
실행 직전엔 무조건 ?에 해당하는 데이터를 지정해야 함
SQL 문을 실행 메소드의 인자로 주지 않음
- ps.execute() : 수행결과가 ResultSet이면 true, 아니면 false 리턴
- ps.executeQuery() : Select문 수행결과를 ResultSet에 담아서 리턴함
- ps.executeUpdate() : Row 수를 리턴
Statement와 다른 점은?
실행시키는 함수의 매개변수가 SQL 문이 아님
--> 매개변수 필요 없기 때문
CallableStatement
- PreparedStatement interface를 상속한 Interface
- Connection 객체의 prepareCall()로 생성
cs = conn.prepareCall(function);
일반 SQL 문과 다른 점은 데이터베이스의 저장 프로시저 등을 실행시키기 위한 Statement라는 것
Stored prodecure/function을 실행하는데 사용됨
- procedure : "{call procedure_name([variable1, variable 1, variable 1, ...])}"
- function : "{?=call function_name([variable1, variable 1, variable 1, ...])}"
variable은 ?로 표현함
String function = "{?=call salary incF(?, ?)}"; // Function Call
String procedure = "{?=call salary inc(?, ?, ?)}"; // procedure Call
INPUT 변수에 값을 Biding하고, OUTPUT 변수의 Type을 설정함
- Input binding : setXXX(index, variable_value) - index는 1부터 시작
- Output 변수 Type 설정 : registerOutParameter(index, Types, XXX)
CallableStatement 실행은 execute() Method를 주로 이용
cs.setInt(2, 1119);
cs.setInt(3, 10);
cs.registerOutParameter(1, Types.INTEGER);
cs.execute();
결과 값은 CallableStatement 객체의 getXxx() 함수 이용
int salary = cs.getInt(1);
실습
게시글 하나를 표현할 수 있는 VO 객체 생성
BoardVO.java
package biz.board;
import java.util.Date;
public class BoardVO {
private int seq;
private String title;
private String writer;
private String content;
private Date regDate;
public int getSeq() {
return seq;
}
public void setSeq(int seq) {
this.seq = seq;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getRegDate() {
return regDate;
}
public void setRegDate(Date regDate) {
this.regDate = regDate;
}
// 편의성을 위해 toString 함수를 오버라이드 받아 VO객체에 데이터 출력함
@Override
public String toString() {
return "BoardVO [seq=" + seq + ", title=" + title + ", writer=" + writer + ", content=" + content + ", regDate="
+ regDate + "]";
}
}
DAO 클래스를 이용하여 게시글 내용이 DB에 저장 또는 DB에서 SELECT 되도록 작업함
BoardDAO.java
package biz.board;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import biz.common.JDBCUtil;
public class BoardDAO {
// connect 객체와 statement 객체가 필요하므로 멤버 변수로 선언
private Connection conn;
private PreparedStatement stmt;
private ResultSet rs;
// SQL 문을 담을 수 있는 변수 선언
// title과 writer와 content는 실제 유저 입력 값으로,
// 첫 번째 컬럼 데이터는 primaryKey 데이터 (board에서 가장 큰 숫자 값을 뽑아 더하기 1)
private static String BOARD_INSERT =
"insert into board (seq, title, writer, content) values "+
"((select nvl(max(seq), 0) + 1, from board), ?,?,?)";
// 전체 목록을 SELECT 하기 위한 SQL 문도 필요
private static String BOARD_LIST = "select * from board";
// 실제 DBMS가 필요할 때 호출되는 함수 선언
public void insertBoard(BoardVO vo) {
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(BOARD_INSERT);
stmt.setString(1, vo.getTitle());
stmt.setString(2, vo.getWriter());
stmt.setString(3, vo.getContent());
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(stmt, conn);
}
}
// 전체 게시글 목록을 뽑기 위해서 호출되는 함수 정의
public List<BoardVO> getBoardList(BoardVO vo){
List<BoardVO> boardList = new ArrayList<BoardVO>();
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(BOARD_LIST);
rs = stmt.executeQuery();
// while 문 안에 작성했을 경우, 게시글이 없다면 false
// while 문이 한번 돌때마다 하나의 게시글이라는 의미
while(rs.next()) {
BoardVO board = new BoardVO();
board.setSeq(rs.getInt("SEQ"));
board.setTitle(rs.getString("TITLE"));
board.setWriter(rs.getString("WRITER"));
board.setContent(rs.getString("CONTENT"));
board.setRegDate(rs.getDate("REGDATE"));
boardList.add(board);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(rs, stmt, conn);
}
return boardList;
}
}
게시글 입력 요청을 위한 Controller 생성
InsertBoardController.java
package controller.board;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import biz.board.BoardDAO;
import biz.board.BoardVO;
import controller.Controller;
public class InsertBoardController implements Controller{
@Override
public String handleRequest(HttpServletRequest request, HttpServletResponse response) {
String title = request.getParameter("title");
String writer = request.getParameter("writer");
String content = request.getParameter("content");
// 유저가 입력한 데이터를 VO로 표현하고 VO에 담음
BoardVO vo = new BoardVO();
vo.setTitle(title);
vo.setWriter(writer);
vo.setContent(content);
// 만들어 놓은 DAO의 함수 호출
// insertBoard 함수 호출 -> 유저 입력 데이터 전달 -> DB에 저장
BoardDAO dao = new BoardDAO();
dao.insertBoard(vo);
// 문자열로 getBoardList.do 화면이 나오도록 리턴
return "getBoardList.do";
}
}
전체 게시글을 보기위한 요청을 처리하는 Controller
GetBoardListController.java
package controller.board;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import biz.board.BoardDAO;
import biz.board.BoardVO;
import controller.Controller;
public class GetBoardListController implements Controller {
@Override
public String handleRequest(HttpServletRequest request, HttpServletResponse response) {
BoardVO vo = new BoardVO();
BoardDAO dao = new BoardDAO();
// DAO가 데이터베이스에서 글을 SELECT하여 리턴시킴
List<BoardVO> boardList = dao.getBoardList(vo);
// 만들어 놓은 getBoardList 함수를 호출하고 결과를 Request 객체에 담음
request.setAttribute("boardList", boardList);
return "getBoardList.jsp";
}
}
이 2개의 Controller를 Mapping에 등록
mappings.put("/insertBoard.do", new InsertBoardController());
mappings.put("/getBoardList.do", new GetBoardListController());
로그인이 성공 상태면 텍스트만 보여지는게 아니라 게시글을 쓸 수 있는 화면으로 넘어가게 한다.
LoginController.java 수정
if(user != null) {
HttpSession session = request.getSession();
session.setAttribute("user", user);
// return "ok.jsp";
return "getBoardList.do";
insertBoard.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>새글 등록</h1>
<hr/>
<form action="insertBoard.do" method="post">
<table border="1">
<tr>
<td>title</td>
<td><input type="text" name="title"/></td>
</tr>
<tr>
<td>writer</td>
<td><input type="text" name="writer"/></td>
</tr>
<tr>
<td>content</td>
<!--길게 작성할 수 있게끔 textarea로 작성-->
<td><textarea name="content" cols="40" rows="10"/>
</textarea>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="add"/></td>
</tr>
</table>
</form>
</body>
</html>
게시글 목록 확인 가능한 파일 생성
getBoardList.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1>board list</h1>
<hr/>
<h3>${user.name } 님 환영합니다. <a href="Logout.do">logout</a></h3>
<table border="1">
<tr>
<td>no</td><td>title</td><td>writer</td><td>date</td>
</tr>
<c:forEach var="board" items="${boardList }">
<tr>
<td>${board.seq }</td>
<td><a href="getBoard.do?seq=${board.seq }">${board.title }</a></td>
<td>${board.writer }</td>
<td>${board.regDate }</td>
</tr>
</c:forEach>
</table>
<!-- 새 글을 등록할 수 있는 화면을 링크로 제공 -->
<br/>
<a href="insertBoard.html">add board</a>
</body>
</html>
테스트
login.html 실행
DB에 등록된 데이터를 넣고 login 버튼 누르면 board list 페이지로 넘어감
add board 클릭
글을 입력하고 add를 눌렀을 때 board list에 추가되면 됨
--
사소한 오류는 있었지만 앞에서 나온 오류랑 같은거라 뚝딱하니 멀쩡히 구동된다
감동이 있네....
'온라인 강좌 > JSP & Servlet 활용' 카테고리의 다른 글
22차시 Project - 게시판 수정, 삭제 (0) | 2023.07.06 |
---|---|
20차시 Project - 인증 (0) | 2023.07.05 |
19차시 Project - 회원등록 (1) | 2023.07.05 |
18차시 Project - 환경 구축 (0) | 2023.07.04 |
17차시 Spring Boot (0) | 2023.07.04 |