<< 학습 목표 >>
1. SELECT 쿼리의 결과를 ResultSet 타입 객체에 저장할 수 있다.
2. ResultSet 타입 객체를 통해 결과를 꺼낼 수 있다.
이전 글에서는 INSERT, UPDATE, DELETE 쿼리를 보내고 결과를 받는 방법을 배웠음
이 글에서는 SELECT 쿼리를 보내고 결과를 받는 방법을 배워보자
우선 SELECT 쿼리를 위해 데이터를 몇 개 추가하자
| INSERT INTO tb(col1, col2, col3) VALUES('1', '첫번째', TIMESTAMP('2023-03-06 14:11:00')); INSERT INTO tb(col1, col2, col3) VALUES('2', '두번째', TIMESTAMP('2023-03-06 14:12:12')); INSERT INTO tb(col1, col2, col3) VALUES('4', '네번째', TIMESTAMP('2023-03-06 14:13:26')); |
chapter04 -> DAO 클래스 내 다음과 같이 select 메서드를 추가하자
public void select() {
try {
Class.forName("org.mariadb.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mariadb://localhost:3306/practice?user=root&password=0000");
String sql = "SELECT * FROM tb";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
int nthIdx = rs.getInt(1);
int nthCol1 = rs.getInt(2);
String nthCol2 = rs.getString(3);
Timestamp nthCol3 = rs.getTimestamp(4);
System.out.println("idx => " + nthIdx);
System.out.println("col1 => " + nthCol1);
System.out.println("col2 => " + nthCol2);
System.out.println("col3 => " + nthCol3);
System.out.println();
}
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
SELECT 쿼리를 보내 실행한 후 결과를 받아올 때는 executeQuery 메서드를 호출해야함(1)
executeQuery 메서드는 SELECT 쿼리로 조회한 데이터들을 ResultSet 타입 객체에 담아서 반환함(2)

executeQuery 메서드가 반환한 ResultSet 타입 객체(SELECT 쿼리의 실행 결과)는 다음과 같이 생겼음
( 조회된 결과 데이터는 제(글쓴이) 상황의 결과임 )

ResultSet 타입 객체의 특징은 Cursor(커서) 가 있음
SELECT 결과를 자바에서 사용하려면 ResultSet 타입 객체를 사용해야함
그리고 자바는 Cursor 위치의 데이터를 꺼낼 수 있음
현재 커서의 위치는 첫 번째 데이터 보다 한 칸 더 위에 있음
조회 결과에서 첫번째 데이터를 꺼내려면 커서를 한 칸 이동 시킨 후 꺼내야함
ResultSet 타입 객체의 커서를 한 칸 이동 시키는 메서드는 next 메서드임
next 메서드는 커서를 이동 시키고 커서가 이동했다면 true를 반환함
만약 커서가 이동하지 못했다면 false를 반환함
우리가 사용한 코드에서는 while문의 조건식에 넣었음(1)

while문의 동작 과정을 알아보자
우선 executeQuery 메서드를 통해 SELECT 결과가 다음과 같은 형태의 ResultSet 타입 객체에 저장되고 이를 rs 객체에 저장했음

현재 rs 객체의 커서가 첫 번째 데이터 보다 한 칸 위에 있으므로 현재 상태에서는 rs 객체에서 조회 결과 데이터를 꺼낼 수 없음
그래서 next 메서드를 호출해서 커서를 한 칸 뒤로 이동 시킨 후 데이터를 꺼내야함
while문을 만나면 조건식의 rs.next 메서드가 동작해 커서가 한 칸 이동함
커서가 이동했으므로 rs.next 메서드는 true 를 반환함

while의 조건식이 true 이므로 while 안의 코드가 실행됨
rs.getInt(n) 메서드는 "현재 rs 객체의 커서가 가리키는 곳의 n번째 칼럼의 값을 int 로 꺼내라" 임

따라서 첫 번째 데이터의 첫 번째 칼럼(idx)의 값이 꺼내짐

그 밑에 있는 코드들은 첫 번때 데이터의 두 번째 칼럼(col1), 세 번째 칼럼(col2), 네 번째 칼럼(col3)의 값을 꺼냄

그 후 꺼낸 값을 Sysout 함

이제 while의 끝을 만나 다시 조건식으로 올라감
조건식의 rs.next 메서드가 동작해 rs 객체의 커서를 다음 칸으로 이동시키고 커서가 이동했으므로 true를 반환함

while의 조건식이 true이므로 while 안으로 들어가 현재 커서가 가리키는 두 번째 데이터의 idx, col1, col2, col3 칼럼의 값을 꺼내고(1) 출력함(2)

while의 끝을 만나 다시 조건식으로 올라감
조건식의 rs.next 메서드가 동작해 rs 객체의 커서를 다음 칸으로 이동시키고 커서가 이동했으므로 true를 반환함

while의 조건식이 true이므로 while 안으로 들어가 현재 커서가 가리키는 두 번째 데이터의 idx, col1, col2, col3 칼럼의 값을 꺼내고(1) 출력함(2)

while의 끝을 만나 다시 조건식으로 올라감
조건식의 rs.next 메서드가 동작해 rs 객체의 커서를 다음 칸으로 이동시키고 커서가 이동했으므로 true를 반환함

while의 조건식이 true이므로 while 안으로 들어가 현재 커서가 가리키는 두 번째 데이터의 idx, col1, col2, col3 칼럼의 값을 꺼내고(1) 출력함(2)

이제 마지막~!
while의 끝을 만나 다시 조건식으로 올라감
조건식의 rs.next 메서드가 동작해 rs 객체의 커서를 다음 칸으로 이동시켜야하는데 커서가 이동할 자리가 없으므로 커서를 옮기지 못하고 false를 반환함

while의 조건식이 false이므로 while을 빠져나가 DB 접속을 끊음

여기까지 SELECT 쿼리를 보내 실행 한 후 결과를 받아오는 방법을 배웠음
또 받아온 결과를 꺼내는 방법까지 배웠음
마지막으로 커서에 대해서 조금 더 이야기하고 마무리 하자
커서는 단방향이기 때문에 next 메서드를 호출해 커서를 밑으로 내릴 순 있지만 위로 올릴 수는 없음
아예 위로 올리는 메서드 자체가 없음
만약 rs.next 를 해서 커서가 이동을 했는데 다시 첫 번째 데이터를 꺼내야한다면 어쩔 수 없이 executeQuery 메서드를 다시 호출해서 검색 결과를 다시 받아와야함
'Servlet + JSP > Serlvet-Chapter04' 카테고리의 다른 글
| Chapter04. CRUD 프로젝트 / 회원가입 (0) | 2023.03.07 |
|---|---|
| Chapter04. 자바의 DB와 관련된 자원은 close 를 해줘야한다. (2) | 2023.03.06 |
| Chapter04. 자바에서 쿼리 보내고 결과 받기 / INSERT, UPDATE, DELETE (0) | 2023.03.06 |
| Chapter04. 자바와 DB 연동 (0) | 2023.03.04 |
| Chapter04. ServletConfig (0) | 2023.03.03 |