오라클 JDBC 불러오기
Java에서 Oracle 데이터베이스에 연결하고 데이터를 조회하는 실습을 해보자. 먼저 JDBCPrjTest 프로젝트에서 오라클 드라이버 라이브러리를 불러오고 Program이라는 클래스를 하나 만들어주자.
사전 테이블 정의
JDBC를 이용하여 데이터를 조회하기 위해서 먼저 Oracle 데이터베이스에 필요한 테이블과 데이터가 정의되어 있어야 한다. 오라클 데이터베이스에서 아래와 같은 쿼리를 실행해 테이블을 정의하자.
JDBC 기본 코드 복습
이전 글에서 설명하였던 Java에서 Oracle 데이터베이스에 접속하고 데이터를 조회하기 위해 사용되는 네 가지 주요 객체이다. 이 객체들은 JDBC를 이용한 데이터베이스 프로그래밍에서 항상 동일하게 사용되는 패턴이기 때문에, 하나의 세트로 외워두면 좋다.
DriverManager: 데이터베이스 드라이버를 로드하고, 데이터베이스 연결을 생성하는 역할을 한다.
Connection: 데이터베이스에 연결을 생성하며, SQL 문을 실행할 수 있는 환경을 제공한다.
Statement: SQL 문을 실행하는 객체로, 쿼리를 데이터베이스에 전달하여 결과를 가져온다.
ResultSet: SQL 쿼리의 결과를 저장하고, 결과 데이터를 탐색할 수 있도록 한다.
그리고 각 객체의 사용이 끝난 후에는 close()를 사용하여 자원을 해제 해주자. 해제하는 순서는 객체 생성의 역순으로 진행해야한다.
url 변수에는 접속할 서버와 데이터베이스에 대한 정보를 넣어준다. 기본 형식은 "jdbc:oracle:thin:@[서버주소]:[포트]/[서비스명]"이며 로컬에서 접속할 경우 서버주소에 "localhost"를 사용할 수 있다.
주의사항으로는 SQL Developer에서 접속할 데이터베이스에 대한 정보와 "jdbc:oracle:thin:@[호스트이름]:[포트번호]/[서비스이름]"에서의 사용하는 정보들이 일치해야 한다.
그리고 공지사항을 저장하는 NOTICE 테이블에 모든 컬럼의 데이터를 조회하는 예시 쿼리인 "SELECT * FROM NOTICE"를 sql 변수에 저장한다.
또한 네 가지 주요 객체들을 생성했다면 ResultSet에서 데이터를 읽기 위해 rs.next()를 호출한다. next()는 커서를 첫 번째 레코드로 이동시켜, 데이터를 가져오게 한다. 그 후 데이터를 가져오려면 컬럼 이름을 사용하여 값을 읽어온다.
실습 시작
먼저 Java에서 Oracle 데이터베이스에 연결하고 데이터를 조회하기 전에 조회 할 데이터를 넣어주자. INSERT INTO NOTICE VALUES(1, 'JDBC란 무엇인가?', 'newlec', 'aaa', SYSDATE, 0, ''); 라는 쿼리를 통해 NOTICE 테이블에 값을 넣어줬다. 이제 이 NOTICE 테이블에 넣은 값에서 TITLE컬럼에 해당하는 값을 꺼내보자.
※ 오라클은 수동 COMMIT이다.
URL 설정
url 변수에 데이터베이스 연결을 위한 URL 정보를 넣어준다. 여기서는 jdbc:oracle:thin:@localhost:1521/xepdb1로 로컬 호스트의 xepdb1 데이터베이스를 가리키고 있다.
SQL 쿼리 작성
sql 변수에는 실행할 SQL 쿼리문을 저장한다. 여기서는 SELECT * FROM NOTICE로 설정되어 있으며, NOTICE 테이블의 모든 데이터를 조회하는 쿼리이다.
데이터베이스 연결
Class.forName("oracle.jdbc.driver.OracleDriver")는 JDBC 드라이버를 로드한다.
DriverManager.getConnection(url, "newlec", "비밀번호")는 지정된 URL과 사용자 이름("newlec"), 비밀번호를 사용하여 데이터베이스에 연결한다.
쿼리 실행 및 결과 처리
Statement st = con.createStatement()는 SQL 문을 실행하기 위한 Statement 객체를 생성한다.
ResultSet rs = st.executeQuery(sql)는 SQL 쿼리를 실행하고, 결과를 ResultSet 객체에 저장한다.
if (rs.next())는 쿼리 결과에서 다음 행이 있는지 확인하고, 있을 경우 데이터를 가져온다.
String title = rs.getString("TITLE")는 결과에서 "TITLE" 컬럼의 데이터를 가져와 title 변수에 저장한다.
System.out.println(title)는 가져온 데이터를 출력한다.
자원 해제
rs.close(), st.close(), con.close()는 사용한 자원을 해제하여 메모리 누수를 방지한다.
아래의 코드를 실행해보면 NOTICE 테이블의 TITLE 컬럼에 해당하는 데이터가 잘 조회된 것을 확인할 수 있다.
개선점
TITLE을 가져올 때는 getString() 메서드를 사용하여 문자열로 가져왔는데, 문자열이 아닌 다른 데이터 형식의 컬럼은 어떻게 가져와야 할까? 컬럼의 데이터 형식에 맞는 get 메서드를 사용해야한다. 예를 들어, 정수형 데이터는 getInt()를, 날짜 형식의 데이터는 getDate()를 사용해야한다.
Date 타입의 경우, Java에서는 java.util.Date와 java.sql.Date 두 가지가 존재한다. 데이터베이스에서 날짜 데이터를 가져올 때는 java.util.Date를 사용해야 한다는 점을 기억하자
또한 현재 코드는 if 문을 사용해 첫 번째 레코드만 가져온다. 두 번째 레코드를 가져오려면 코드를 복사하여 추가할 수 있지만, 이것은 비효율적인 방법이다. 모든 레코드를 가져오려면 반복문을 사용하는 것이 바람직할 것이다. while 문을 사용하여 ResultSet의 모든 레코드를 처리해보자
만약 조회수(hit)가 10 이상인 게시글만 출력되도록 하려면 어떻게 해야할까? 아래 좌측 그림은 자바에서 처리한 경우이고 아래 우측 그림은 SQL로 필터링한 경우이다. 어떤것이 더 올바른 방법일까? SQL로 필터링하게 한 코드가 더 바람직한 코드이다. 사용자가 볼 때 결과는 같겠지만 성능과 효율성 측면에서 매우 다르다.
예를 들어 게시글이 1억 개가 있다고 가정해보자. 이 경우, while 문 내부에서 조건을 체크하면 1억 번의 반복이 필요하다. 1억 개의 데이터를 네트워크를 통해 가져오고, 그중에서 조건에 맞는 몇 개만 출력하는 방식이니 매우 비효율적이다.
그래서 오라클 같은 DBMS에 데이터 필터링, 정렬, 그룹핑 등 다양한 데이터를 가공하는 작업은 DBMS에게 맡기고, 자바는 그 데이터를 사용자에게 어떤 포맷으로 보여줄지에만 집중하는 것이 올바른 역할 분담일 것이다.
이렇게 하면 자바에서의 개발이 훨씬 수월해지고, 애플리케이션의 성능도 크게 향상된다. 즉, SQL을 잘 활용하면 자바 개발의 많은 부분이 간소화될 수 있다.
그래서 앞으로 우리는 SQL을 열심히 공부해서 데이터 필터링, 정렬, 그룹화 등의 모든 데이터 연산은 데이터베이스에서 처리하도록 해야한다.
참고자료
[1] 유튜브 채널 뉴렉처 - 쿼리 실행하기 실습
'🖥️ Backend > JDBC' 카테고리의 다른 글
[JDBC] 3.JDBC 기본 코드의 이해 (0) | 2024.08.24 |
---|---|
[JDBC] 2.오라클 JDBC Driver 다운로드 및 불러오기 (0) | 2024.08.23 |
[JDBC] 1.JDBC란 무엇인가? (0) | 2024.08.21 |