인라인뷰 참고 블로그
[SQL] 서브 쿼리의 개념과 별칭(ALIAS) 사용하기 (tistory.com)
[SQL] 서브 쿼리의 개념과 별칭(ALIAS) 사용하기
서브 쿼리란? 서브 쿼리는 하나의 SELECT 문장에서 그 문장 안에 포함된 또 하나의 SELECT 문장입니다. 서브 쿼리를 순차적으로 사용하여 복잡한 쿼리문을 쉽게 구현할 수 있습니다. 기본 사용법 SELE
lifejusik1004.tistory.com
15일 페이지 처리 sql문
--1) 모든 정보 읽어오기
SELECT * FROM smboard ORDER BY num DESC;
--2) rownum(행번호) 출력 (from 절의 서브쿼리 행 만큼)
SELECT rownum FROM (SELECT * FROM smboard ORDER BY num DESC);
--3) rownum + 행 전체 출력 / 오류
SELECT *, rownum FROM (SELECT * FROM smboard ORDER BY num DESC);
-- *와 다른 컬럼명을 함께 쓰면 오류
--4) rownum + 행 전체 출력
SELECT a.*, rownum FROM (SELECT * FROM smboard ORDER BY num DESC)a;
--5) 행 번호가 1~10인 데이터만 출력
SELECT a.*, rownum FROM (SELECT * FROM smboard ORDER BY num DESC)a
WHERE rownum >= 1 AND rownum <= 10;
--5-2) 5번 방법으로 11~20행 데이터 출력 / 오류
SELECT a.*, rownum FROM (SELECT * FROM smboard ORDER BY num DESC)a
WHERE rownum >= 11 AND rownum <= 20;
--6) 서브쿼리 2개 겹쳐서 1~10 행번호 출력 (rownum+알리아스명)
SELECT * FROM (SELECT a.*, rownum rnum FROM (SELECT * FROM smboard ORDER BY num DESC)a)
WHERE rnum >= 1 AND rnum <= 10;
--6-2) 6번 방법으로 11~20행 데이터 출력
SELECT * FROM (select a.*, rownum rnum FROM (SELECT * FROM smboard ORDER BY num DESC)a)
WHERE rnum >= 11 AND rnum <= 20;
기존 DAO의 getList 등 수정
kr.util (package)
PagingUtil.java
mbox에서 내려받고 붙여넣기 (페이지 연산에 필요한 가공 처리하는 클래스)
BoardDAO
package kr.board.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import kr.board.vo.BoardVO;
import kr.util.DBUtil;
public class BoardDAO {
//싱글턴 패턴 구성 후 작업해야함
//싱글턴 패턴
private static BoardDAO instance = new BoardDAO();
public static BoardDAO getInstance() {
return instance;
}
//생성자를 private으로 막음 -> getInstance를 호출해서 사용 (하나 만들어서 계속 공유)
private BoardDAO() {}
//글 저장
public void insert(BoardVO boardVO)throws Exception{ //반환하는 데이터가 없어서 void로 만듦
//DAO 메서드 만드는 방법
//1) 변수 선언 -> try~catch 구조 만들기
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
//커넥션풀로부터 커넥션을 할당받음
conn = DBUtil.getConnection(); //1~2단계 수행
//SQL문 작성
sql = "INSERT INTO smboard (num,title,name,passwd,content,ip) VALUES (smboard_seq.nextval,?,?,?,?,?)";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setString(1, boardVO.getTitle()); //자바빈에 데이터를 담아서 가져오는거라 뽑아내야함
pstmt.setString(2, boardVO.getName());
pstmt.setString(3, boardVO.getPasswd());
pstmt.setString(4, boardVO.getContent());
pstmt.setString(5, boardVO.getIp());
//SQL문 실행
pstmt.executeUpdate();
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(null, pstmt, conn);
}
}
//글의 총 개수 (페이지 처리 하기 위해)
public int getCount()throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
int count = 0;
try {
//커넥션풀로부터 커넥션을 할당
conn = DBUtil.getConnection();
//SQL문 작성
sql = "SELECT COUNT(*) FROM smboard"; // smboard로부터 전체 개수 읽어옴 (결과->1행)
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//SQL문 실행
rs = pstmt.executeQuery();
if(rs.next()) { //count는 출력 행이 하나기 때문에 if문 사용
count = rs.getInt(1); //본래는 COUNT(*)인데 기호가 들어가기도 하고, 값이 하나라서 그냥 컬럼 인덱스를 썼음
}
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(rs, pstmt, conn);
}
return count;
}
//글 목록 (list.jsp에 반환)
//VO에 하나의 레코드를 넣을거임, 여러개의 VO를 통합해서 List타입으로 arraylist객체 만들고 반환
public List<BoardVO> getList(int startRow, int endRow)throws Exception{ //반환타입이 List타입
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<BoardVO> list = null;
String sql = null;
try {
//커넥션풀로부터 커넥션을 할당받음
conn = DBUtil.getConnection();
//SQL문 작성
sql = "SELECT * FROM (SELECT a.*, rownum rnum FROM (SELECT * FROM smboard ORDER BY num DESC)a) WHERE rnum >= ? AND rnum <= ?";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setInt(1, startRow);
pstmt.setInt(2, endRow);
//SQL문 실행
rs = pstmt.executeQuery();
list = new ArrayList<BoardVO>(); //데이터를 하나의 객체로 묶어서 return 하기 위해 arrayList 생성
while(rs.next()) { //행에 접근 후 자바빈에 데이터 저장
BoardVO boardVO = new BoardVO(); //자바빈 생성
boardVO.setNum(rs.getInt("num"));
boardVO.setTitle(rs.getString("title"));
boardVO.setName(rs.getString("name"));
boardVO.setReg_date(rs.getDate("reg_date"));
//자바빈(VO)을 ArrayList에 저장
list.add(boardVO);
}
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(rs, pstmt, conn);
}
return list;
}
//글 상세
public BoardVO getBoard(int num)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
BoardVO board = null;
String sql = null;
try {
//커넥션풀로부터 커넥션 할당
conn = DBUtil.getConnection();
sql = "SELECT * FROM smboard WHERE num=?";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setInt(1, num);
//SQL문 실행
rs = pstmt.executeQuery();
if(rs.next()) { //행이 1개라서 if문 (여러 개면 while)
board = new BoardVO(); //자바빈 객체 생성
board.setNum(rs.getInt("num")); //자바빈에 데이터 담기
board.setTitle(rs.getString("title"));
board.setName(rs.getString("name"));
board.setPasswd(rs.getString("passwd"));
board.setContent(rs.getString("content"));
board.setIp(rs.getString("ip"));
board.setReg_date(rs.getDate("reg_date"));
}
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(rs, pstmt, conn);
}
return board; //자바빈 반환
}
//글 수정
//위 getBoard를 이용해서 글이 있는지 없는지 인증 후 수정
public void update(BoardVO boardVO)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
//커넥션풀로부터 커넥션 할당
conn = DBUtil.getConnection();
//SQL문 작성
sql = "UPDATE smboard SET title=?,name=?,content=?,ip=? WHERE num=?";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setString(1, boardVO.getTitle());
pstmt.setString(2, boardVO.getName());
pstmt.setString(3, boardVO.getContent());
pstmt.setString(4, boardVO.getIp());
pstmt.setInt(5, boardVO.getNum());
//SQL문 실행
pstmt.executeUpdate();
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(null, pstmt, conn);
}
}
//글 삭제
//인증은 getBoard에서 할거기 때문에 여기서 다른 인증은 따로 X (getBoard->delete)
public void delete(int num)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
//커넥션풀로부터 커넥션 할당
conn = DBUtil.getConnection();
//SQL문 작성
sql = "DELETE FROM smboard WHERE num=?";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setInt(1, num);
//SQL문장 실행
pstmt.executeUpdate();
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(null, pstmt, conn);
}
}
}
글의 총 개수 / 목록보기 수정
list.jsp
get 방식으로 번호를 넘겨서 보이게 하는건데 처음 들어가게 되면 무조건 null을 가짐 (넘겨주지 않아서)
-> null일 경우에 무조건 1페이지 보이게 설정
페이지 설정 순서
1) 처리 설정 정보 (rowCount, pageCount, currentPage)
2) list 부분에 count 조건 체크
count==0 저장된 글 없다는 문장 출력
count > 0 list=startRow(), endRow()
3) 목록 출력
4) 페이지 표시 util.getPage()
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="kr.board.dao.BoardDAO" %>
<%@ page import="kr.board.vo.BoardVO" %>
<%@ page import="java.util.List" %>
<%@ page import="kr.util.PagingUtil" %>
<%
//선택한 페이지 번호
String pageNum = request.getParameter("pageNum"); // 쌤이 준 파일 사용할 경우에는 pageNum식별자가 정해져있음 이걸써야함
//pageNum이 전송되지 않으면 1페이지로 처리 (처음엔 아무것도 없어서 pageNum==null임)
if(pageNum == null){
pageNum = "1";
}
//페이지 처리에 대한 설정정보 (int row/pageCount, currentPage)
//1) 한 화면에 몇 개의 글(행, 레코드)를 보여줄 지 지정
int rowCount = 10; //얘를 조정하면 얼마나 보일지 조정 가능
//한 화면에 몇 개의 페이지 수를 보여줄 지 지정 (1~10 다음)
int pageCount = 10;
//현재 선택한 페이지 타입 변환(String -> int / 연산하기 위해)
int currentPage = Integer.parseInt(pageNum);
BoardDAO dao = BoardDAO.getInstance();
int count = dao.getCount(); //총 레코드 수
//페이지 처리
PagingUtil util = new PagingUtil(currentPage, count, rowCount, pageCount, "list.jsp"); //마지막은 주소 호출
List<BoardVO> list = null;
if(count>0){
list = dao.getList(util.getStartRow(), util.getEndRow());
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 목록</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="page-main">
<h1>게시판 목록</h1>
<div class="align-right">
<input type="button" value="글쓰기" onclick="location.href='writeForm.jsp'">
</div>
<%
if(count==0){
%>
<div class="result-display">저장된 글이 없습니다.</div>
<%
}else{
%>
<!-- 목록 출력 시작 -->
<table>
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
</tr>
<%
//루프 돌면서 출력
for(BoardVO boardVO : list){ //arraylist로부터 boardVO를 뽑아냄 (get메서드 사용)
%>
<tr>
<td><%= boardVO.getNum() %></td>
<td><a href="detail.jsp?num=<%= boardVO.getNum() %>"><%= boardVO.getTitle() %></a></td>
<td><%= boardVO.getName() %></td>
<td><%= boardVO.getReg_date() %></td>
</tr>
<%
}
%>
</table>
<!-- 목록 출력 끝 -->
<!-- 페이지 표시 시작 -->
<div class="align-center">
<%= util.getPage() %>
</div>
<!-- 페이지 표시 끝 -->
<%
}
%>
</div>
</body>
</html>
==다시 정리
1) boardDAO getCount() 메서드
select count(*) from smboard 를 통해 글의 총 개수를 구함
컬럼명이 count(*) 로 기호가 들어가 있어서 컬럼명 대신 컬럼인덱스를 명시, if(rw.next())로 sql문 실행
2) boardDAO getList() 메서드
getList(int startTow, intendRow) 메서드를 넣어 1, 10/ 11, 20 이런 식으로 보이게 함
sql문 >
select * from (select a.*, rownum rnum from
(select * from smboard order by num desc)a)
where rnum>=startRow and rnum<=endRow;
3) list.jsp
boardVO.getNum 부분에서 목록 보이게 하기
4) 초기화면
처음엔 선택한 페이지가 없어서 pageNum==null
pageNum==null일 경우에 1page가 보이게 설정해놓음
[실습] 기본적인 형태 학습하기
회원 관리 + 보드 형식을 합쳐서 회원제 보드 형태로 사용하려고 함
(사원관리 + 사원들이 글을 올리고 삭제 및 수정할 수 있는 게시판 생성)