Connection conn = null;
PreapredStatement pstmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
pstmt = conn.prepareStatement("SELECT * FROM member WHERE email=?");
pstmt.setString(1, email);
rs = pstmt.executeQuery();
if (rs.next()) {
member = new Member(rs.getString("email"),
rs.getString("password"),
rs.getString("name"),
rs.getString("regdate"));
member.setId(rs.getLong("ID"));
return member;
} else {
return null;
}
} catch (SQLException e) {
e.printStackTrace();
throw e;
} finally {
if(rs!=null) try {rs.close();}catch(SQLException ex) {}
if(pstmt!=null) try{pstmt.close();}catch(SQLException ex) {}
if(conn!=null) try{conn.close();}catch (SQLException ex) {}
}
국비 교육에서 그저 따라치기만 했던 이 DB연동 코드를 구체적으로 분석해보자!
의미 그대로 자바에서 DB에 접근하기 위한 연결 방식을 제공하는 API(라이브러리) 이다. 우리는 JDBC를 통해 자바 언어로 데이터베이스에 있는 데이터를 조작할 수 있다.
MySQL, Oracle 등등 다양한 DB는 각기 다른 구조와 특징을 가지고 있어 Java에서 해당 DB의 데이터 접근이 쉽지 않았다. 이런 한계를 극복하고자 JDBC 인터페이스와 클래스를 개발해 통신을 돕는다.
가볍게 요약하자면,Connection, ResultSet, PreparedStatement같은 인터페이스를 각각의 DB에서 구체적으로 구현해 놓았다. 우리는 JDBC의 드라이버를 갈아끼우면서 원하는 DB에 접근하고, 공통적으로 구현되어있는 Connection, ResultSet등 인터페이스의 클래스를 통해 동일한 방식으로 DB를 사용할 수 있다.
< JDBC를 활용한 DB 프로그램 구현 4단계 >
1. JDBC 드라이버 로드(드라이버 필요)
2. DB연결(URL, 계정명, 패스워드)
3. PreparedStatement 객체를 통해 SQL 구문 전달 및 실행
4. SQL 구문 실행 후 결과 처리
DB와 연결하는 Driver class를 만들 때 반드시 implements해야 하는 interface로 JDBC의 중심이 되는 Interface이다. 기본적으로 JDBC Driver는 각 DB 벤더(vendor. supplier. db회사)들이 제공하며 DB 통신에 필요한 프로토콜, 네트워크 통신, SQL 파싱 및 실행 등의 기능을 제공한다. 우리는 이 드라이버를 통해 자바와 DB사이의 파이프를 연결할 수 있으며, 이 드라이버를 바꿔가며 원하는 DB를 선택할 수 있다.
try{
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
Class.forName()
으로 특정 클래스를 로딩하면 로드될 때 자신의 인스턴스를 생성하고, 자동으로 DriverManager 클래스 메서드를 호출하여 인스턴스를 등록한다. 따라서, 초기에 Class.forName을 통해 클래스를 로딩했으면 다시 로드를 반복할 필요없다.
특정 데이터베이스와 연결정보를 가지는 Inteface로, DriverManager로부터 Connection 객체를 가져온다. Connection을 통해 데이터베이스에 대한 연결을 설정하고, SQL문을 실행하며, 결과를 가져 올 수 있다.
try{
String dbURL = "jdbc:mysql://localhost:3306/java";
String dbID = "1234";
String dbPassword="1234";
conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
} catch (Exception e) {
e.printStackTrace();
}
Statemet의 하위 Inteface로 SQL문을 미리 컴파일하여 실행 속도를 높인다는 특징이 있다. 동일한 SQL문이 반복적으로 사용되거나 파라미터를 주입해야 하는 경우 Statement보다 PreparedStatement 사용이 권장된다.
Statement 객체의 SQL은 실행될 때 매번 서버에서 분석되어야 하는 반면, PreparedStatement 객체는 한번 분석되면 재사용이 용이하다는 장점을 가지고 있다.
PreparedStatement 인터페이스는 각각의 인수에 대해 위치홀더(placehodler)를 사용하여 SQL 문장을 정의할 수 있다. 위치홀더는 물음표('?')로 표현된다. 위치홀더는 sql 문장에 나타나는 토큰(Token)인데, 이것은 SQL 문장이 실행되기 전에 실제 값으로 대체된다. 이런 방법을 이용하면 특정 값으로 문자열을 연결하는 방법보다 훨씬 쉽게 SQL 문장을 만들 수 있다.
try {
String SQL = "SELECT * FROM board WHERE num =?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
}
PreparedStatement객체의 executeXXX() 메서드 호출
SQL문에서 SELECT문을 사용한 질의의 경우 성공 시 결과물로 ResultSet을 반환한다. ResultSet은 SQL 질의에 의해 생성된 테이블을 담고 있다. 또한 ResultSet 객체는 '커서(cursor)'라고 불리는 것을 가지고 있는데, 그것으로 ResultSet에서 특정 행에 대한 참조를 조작할 수 있다.
ResultSet 객체의 next() 메서드는 뒤에 레코드가 존재할 경우 true를 리턴하는는데, while문 혹은 if문을 통해 해당 메서드를 활용하여 결과물을 출력할 수 있다.
while(rs.next()) {
int idx = rs.getInt("idx");
}
Connection conn = null;
PreapredStatement pstmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
pstmt = conn.prepareStatement("SELECT * FROM member WHERE email=?");
pstmt.setString(1, email);
rs = pstmt.executeQuery();
if (rs.next()) {
member = new Member(rs.getString("email"),
rs.getString("password"),
rs.getString("name"),
rs.getString("regdate"));
member.setId(rs.getLong("ID"));
return member;
} else {
return null;
}
} catch (SQLException e) {
e.printStackTrace();
throw e;
} finally {
if(rs!=null) try {rs.close();}catch(SQLException ex) {}
if(pstmt!=null) try{pstmt.close();}catch(SQLException ex) {}
if(conn!=null) try{conn.close();}catch (SQLException ex) {}
}
JAVA로 다양한 회사의 DB에 접근하기 위해, JDBC라는 하나의 추상화가 존재하고, 각 회사는 이 추상화를 구현하여 "드라이버"라는 통로를 제공하고 있다. 개발자는 어떤 드라이버 클래스를 사용할지 선택함으로써 사용할 DB를 선택할 수 있다.
Class.forName("com.mysql.jdbc.Driver");
특정 드라이브의 인스턴스를 생성한다. 고로 초기에 한번 수행하면 된다.
conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
DriverManager로부터 특정 DB의 Connection 객체를 가져온다. Connection을 통해 DB에 연결하고 SQL문을 실행하며, 결과를 가져올 수 있다.
String SQL = "SELECT * FROM board WHERE num =?";
PreparedStatement pstmt = con.prepareStatement(sql);
PreparedStatement를 통해 SQL문을 실행한다.
while(rs.next()) {
int idx = rs.getInt("idx");
}
ResultSet을 통해 원하는 결과값을 출력한다.