https://www.youtube.com/playlist?list=PLq8wAnVUcTFWxwoc41CqmwnO-ZyRDL0og
강의를 듣고 정리한 내용입니다
페이징을 위한 쿼리 만들기
1부터 10까지의 ROWNUM을 검색하는 SQL문
SELECT ROWNUM, NOTICE. * FROM NOTICE
WHERE ROWNUM BETWEEN 1 AND 10;
위 구문의 문제점 : BETWEEN 2 AND 10;인 경우 조회되지 않는다
해결법 : 서브쿼리를 이용한다(안에서 만들어진 번호)
SELECT * FROM ( SELECT ROWNUM NUM, NOTICE. * FROM NOTICE)
WHERE NUM BETWEEN 2 AND 10;
최신글 순서대로 정렬하기
SQL문
SELECT * FROM NOTICE ORDER BY REGDATE DESC;
서브 쿼리 활용(제대로 출력되지 않음)
SELECT * FROM (SELECT ROWNUM NUM, NOTICE.* FROM NOTICE ORDER BY REGDATE DESC)
WHERE NUM BETWEEN 1 AND 10;
-> ROWNUM을 구한 다음에 정렬되기 때문에 일련번호가 엉키게 된다
-> 서브쿼리가 한 개 더 필요하다
↓
서브 쿼리 활용(바꾼 버전)
SELECT * FROM (SELECT ROWNUM NUM, N.* FROM
(SELECT * FROM NOTICE ORDER BY REGDATE DESC) N //N은 Notice의 별칭
) WHERE NUM BETWEEN 11 AND 20;
페이징 쿼리 이용하기
만든 서브 쿼리를 NoticeService에 넣고 코드를 수정한다
1. getList에 int page값을 넣어준다
public List<Notice> getList(int page) throws Exception
String sql = "SELECT * FROM (" + " SELECT ROWNUM NUM, N.* FROM (" +
" SELECT * FROM NOTICE ORDER BY REGDATE DESC" + " ) N " +
") " + "WHERE NUM BETWEEN ? AND ?";
2. 위치 홀더인 “?“가 있기 때문에 Statement를 Preparedstatement로 바꾼다
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, start); //값을 할당한다
pstmt.setInt(2, end);
ResultSet rs = pstmt.executeQuery();
-> pstmt에서 sql을 불러왔기 때문에 executeQuery()에서는 sql을 없애야 한다
3. start와 end 값을 넣어준다
int start = 1 + (page - 1) * 10; //등차수열 활용 1, 11, 21, 31
int end = 10 * page; //10, 20, 30
NoticeService 바뀐코드 전체 정리
public List<Notice> getList(int page) throws ClassNotFoundException, SQLException {
int start = 1 + (page - 1) * 10; //등차수열 활용 1, 11, 21, 31
int end = 10 * page; //10, 20, 30
String sql = "SELECT * FROM (" + " SELECT ROWNUM NUM, N.* FROM (" +
" SELECT * FROM NOTICE ORDER BY REGDATE DESC" + " ) N " +
") " + "WHERE NUM BETWEEN ? AND ?";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, userId, pwd);
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, start);
pstmt.setInt(2, end);
ResultSet rs = pstmt.executeQuery();
NoticeConsole
service.getList(); 괄호안에 값을 할당하여 출력을 확인한다
List<Notice> list = service.getList(1);
List<Notice> list = service.getList(2);
목록을 위한 View 생성하기
view를 만드는 sql문
CREATE VIEW NOTICE_VIEW AS
SELECT * FROM (SELECT ROWNUM NUM, N.* FROM
(SELECT * FROM NOTICE ORDER BY REGDATE DESC) N(별칭)
);
VIEW를 이용하면 긴 서브쿼리 대신 코드 한 줄로도 조회가 가능하다
SELECT * FROM NOTICE_VIEW WHERE NUM BETWEEN 11 AND 20;
현재 자바 코드의 문제점 : 문자열들을 더하는 작업이 많고 내려쓰기가 너무 많다
-> NoticeService.java 코드 수정
수정 전
String sql = "SELECT * FROM (" + " SELECT ROWNUM NUM, N.* FROM (" +
" SELECT * FROM NOTICE ORDER BY REGDATE DESC" + " ) N " +
") " + "WHERE NUM BETWEEN ? AND ?";
↓
수정 후
String sql = "SELECT * FROM NOTICE_VIEW WHERE NUM BETWEEN ? AND ?";
이전 / 다음 구현하기
1. 페이지를 기록하기 위한 상태 변수 생성
int page;
2. NoticeConsole이 페이지의 상태값을 가지고 있도록 선언 한다
private int page;
public NoticeConsole() {
service = new NoticeService();
page = 1;
}
3. Program5로 돌아와서 switch문의 case 2와 case 3를 수정한다
while(true) {
console.printNoticeList();
int menu = console.inputNoticeMenu();
switch(menu) {
case 1 : //상세조회
break;
case 2 : //이전
console.movePrevList();
break;
case 3 : //다음
console.moveNextList();
break;
4. NoticeConsole movePrevList() 메서드 생성
public void movePrevList() {
if(page == 1) {
System.out.println("이전 페이지가 없습니다.");
return;
}
page--;
}
// moveNextList() 메서드
public void moveNextList() {
page++;
}
마지막 페이지를 알 수 없기에 마지막 페이지를 구하는 로직이 필요하다
-> printNoticeList() 메서드의 list값을 page로 바꾼다
List<Notice> list = service.getList(page);
'백엔드 > Database' 카테고리의 다른 글
Jdbc(ojdbc) 검색 서비스 추가하기 | TIL_140 (0) | 2022.09.02 |
---|---|
Jdbc(ojdbc) 게시글 개수, 마지막 페이지 | TIL_139 (2) | 2022.08.31 |
Jdbc(ojdbc) 사용자 인터페이스 | TIL_137 (0) | 2022.08.24 |
Jdbc(ojdbc) crud 서비스 클래스 | TIL_136 (0) | 2022.08.19 |
트랜잭션 / 데이터 추가 사이트 | TIL_135 (0) | 2022.08.17 |