• Home
  • About
    • on Weekend photo

      on Weekend

      𝙎𝙩𝙪𝙙𝙮𝙞𝙣𝙜

    • Learn More
    • Instagram
    • Github
  • Archive
    • All Posts
    • All Tags
    • All Categories
  • Categories
    • Problem Solving
    • TIL
    • Study
    • Etc
    • 필사
  • Projects

ResultSet : SELECT의 결과를 저장하는 객체

05 Jan 2021

𝐑𝐞𝐬𝐮𝐥𝐭𝐒𝐞𝐭

ResultSet은 SELECT문의 결과를 저장하는 객체입니다.
자바에서 DriverManager로부터 connection 객체를 받아와 jdbc와의 연결을 만든 후, SELECT 쿼리를 돌린다고 가정해봅시다.

String driver = "oracle.jdbc.driver.OracleDriver";
String url = "...";
String id = "...";
String pw = "...";

Connection con = null;
Statement stmt = null;
ResultSet res = null;

/*
DB는 네트워크 연결의 문제 등에서 에러가 발생할 수 있습니다. 이에 **반드시** try-catch 문으로 에러를 잡아 StackTrace를 통해 추후 Exception이 발생한 위치를 정확히 알 수 있도록 합니다.
*/
try {
  Class.forName(driver);

  con = DriverManager.getConnection(url, id, pw);
  stmt = con.createStatement();
  String sql = "SELECT * FROM book";

  // 여기 ResultSet 객체가 사용됩니다!!!!!!!!!
  res = stmt.executeQuery(sql);

  // ResultSet 객체를 이용해, SELECT문의 결과를 순회하여 원하는 값만 뽑아오거나 출력할 수 있습니다.
  while(res.next()) {
    int bookId = res.getInt("book_id");
    String bookName = res.getString("book_name");
    String bookLoc = rest.getString("book_loc");

    out.print("bookId : " + bookId + ", ");
    out.print("bookName : " + bookName + ", ");
    out.print("bookLoc : " + bookLoc + "</br>");
  }
} catch (Exception e) {
  e.printStackTrace();
} finally {
  try {
    /*
    ResultSet, Statement, Connection이 null이 아니라면, 즉 어떠한 데이터를 받아오는 등 프로그램에 의하여 사용되었다면, 리소스 관리를 위해 반드시 종료헤줍니다.
    */
    if(res != null) res.close();
    if(stmt != null) stmt.close();
    if(con != null) con.close();
  } catch (Exception e2) {
    e2.printStackTrace();
  }
}

위의 코드에서 사용되었듯, ResultSet은 SELECT의 결과를 저장하는 객체입니다. 이때 Cursor는 ResultSet이 결과값으로서 받아온 SQL 테이블을 각 행을 가리킵니다. 마치 자바의 자료구조를 순회할 때 쓰는 iterator처럼, Cursor는 테이블 각 행을 이동하며 그 값을 확인할 수 있게끔 해줍니다.

Cursor는 처음에 Before the first row를 가리키고 있습니다. 마치 iterator를 처음 받아왔을 때에, 첫 번째 노드가 아닌 그 앞의 무언가를 가리키고 있는 것과 같습니다. iterator의 쓰임새를 다시 복기해보겠습니다.

Java Iterator

List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
  String name = iterator.next();
  System.out.println(name);
}

ResultSet

while(res.next()) {
  int bookId = res.getInt("book_id");
  String bookName = res.getString("book_name");
  String bookLoc = rest.getString("book_loc");

  out.print("bookId : " + bookId + ", ");
  out.print("bookName : " + bookName + ", ");
  out.print("bookLoc : " + bookLoc + "</br>");
}

위의 코드처럼 노드가 있긴 한건지 먼저 확인하고(hasNext()) 요소를 받아오기 시작합니다. 만약 확인하지 않고 다짜고짜 가져왔는데, 대상이 null이라면 NullPointerException이 발생하겠죠? 이를 방지하기 위해 애초부터 첫 번째 노드 그 이전의 어떠한 시작점을 가리키고 있습니다.

이제 이러한 Cursor를 next() 메소드를 활용해 그 값을 가져오게 됩니다. next()메소드는 더이상 행이 존재하지 않을 때까지 true를 리턴해주게 됩니다.
res.getXXX()을 이용해 컬럼도 하나씩 가져올 수 있습니다. getXXX()에 파라미터로 (1) 컬럼 순서, (2) 컬럼 이름이 들어올 수 있는데요. 위의 예제의 경우 파라미터로 (2) 컬럼 이름이 들어온 것입니다.

내친김에 (1) 컬럼 순서로 데이터를 조회하는 부분도 살펴보겠습니다. 가령 데이터베이스에서 bookName과 bookPrice를 가져온다면,

while(res.next()) {
  String bookName = res.getString(1);
  String bookPrice = res.getInt(2);
}

위의 방식이 되겠네요.


𝑹𝒆𝒇𝒆𝒓𝒆𝒏𝒄𝒆

  1. stack trace가 무엇인가요?
  2. ResultSet이란?


jdbcbackend Share Tweet +1