본문 바로가기
카테고리 없음

11.16일 (model-1 DB연동/ 게시판 목록 및 페이지 처리)

by 쿠룽지 2023. 11. 17.
728x90
반응형

 

 

인라인뷰 참고 블로그

[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가 보이게 설정해놓음

 

 

 


 

 

[실습] 기본적인 형태 학습하기

 

회원 관리 + 보드 형식을 합쳐서 회원제 보드 형태로 사용하려고 함

(사원관리 + 사원들이 글을 올리고 삭제 및 수정할 수 있는 게시판 생성)

 

 

728x90
반응형