무단 도용을 금합니다. (꼭 출저를 써주시길 부탁드립니다.)
개발 환경
- Java : jdk-1.7.0-xx
- 툴 : Eclipse kepler EE
- DBMS : MySQL Community Server 5.6
JDBC연결에 관련된 글은 아래 링크를 참고해주세요.
전에 JDBC 연결에 이어 이번엔 기본적인 아래의 4가지 요소에 대해서 알아보려고 합니다.
JDBC프로그램에 필요한 3가지 인터페이스
- Connection
- Statement (PreparedStatement)
- ResultSet
또 이번에 예제에 필요한 데이터베이스와 테이블의 구조는 간단하게 아래와 같습니다.
CREATE DATABASE dbtest; --데이터베이스의 이름은 dbtest입니다.
CREATE TABLE test_table( --dbtest에 만들 테이블의 이름은 test_table이라고 하겠습니다.
no int auto_increment ,
name varchar(10) not null,
temp int,
PRIMARY KEY(no)
);
Connection
1.Connection 객체 초기화 하기
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
…
private Connection conn = null;
위와같은 객체를 생성했다고 가정하고 Connection 인터페이스의 비어있는 private 멤버 객체(이하 conn)를 만들었습니다.
이 conn이라는 객체에 인스턴스를 생성해주기위해서 해당 DBMS의 드라이버를 설정해 줘야합니다.
1.1 인스턴스 얻기
인스턴스를 얻기 위해서는 DriverManager의 getConnection()이라는 메서드를 이용해야합니다.
이 메서드는 데이터베이스에 연결하는 실질적인 메서드라고 보면 됩니다.
getConnection메서드는 다음 3가지를 파라메터로 받아야합니다.
- url : DBMS의 데이터베이스 접속경로입니다. jdbc:로 시작되는 패턴을 가지고 있으며 형식은 DBMS마다 다릅니다.
- user : DBMS를 접속할때 사용하는 유저 아이디입니다.
- password : DBMS를 접속할때 사용하는 유저의 패스워드입니다.
public Connection getConnection() {
String url = "jdbc:mysql://localhost:3306/dbtest"; //dbtest라는 이름을 가진 DB의 url
String user = "root"; //DBMS 유저 아이디
String password = "1234"; //DBMS 유저 암호
try{
Class.forName("com.mysql.jdbc.Driver"); //connector의 드라이버 클래스 로드
conn = DriverManager.getConnection( url , user , password ); //JDBC연결 (이곳에서 conn의 인스턴스를 얻는다)
return conn;
} catch (ClassNotFoundException | SQLException e) {
System.out.println(e.getMessage());
return null;
}
}
이 소스에서 연결에 실패하여 예외가 발생했다면 두가지 원인으로 볼 수 있습니다.
- ClassNotFoundException : Class.forName메서드가 매개변수인 드라이버를 찾지 못해 발생하는 예외입니다.
이곳을 참고하세요 - SQLException : MySQL서비스가 실행되고있지 않거나 JDBC연결 정보가 잘못 입력 되어 예외가 발생한 것입니다.
Statement와 PreparedStatement
둘 중 어떤것을 써야할까요?
Statement와 PreparedStatement는 각각의 장단점이 있어서
구현할 기능에 따라 이 둘을 적절히 사용하는 것이 좋다고 생각합니다.
출처 :http://www.falkhausen.de/en/diagram/html/java.sql.Statement.html
링크는 제가 자주 참고하는 독일의 한 자바 문서(?) 사이트입니다.
Statement와 PreparedStatement는 JDBC프로그램에서 아주 중요한 역할을 하고있는 인터페이스입니다.
SQL문장을 실행하고 결과를 반환하는 기능들을 캡슐화한 인터페이스로 프로그램 내에서 제일 빈번하게 쓰이는 객체입니다.
먼저 Statement를 살펴보도록 해요.
1.Statement
Statement의 주요 메서드는 아래와 같습니다.
메서드명(파라메터) |
리턴타입 |
기능 |
execute(String sql) | boolean | sql문을 실행하고 성공하면 false가 리턴됩니다. |
executeQuery(String sql) |
ResultSet |
sql문을 실행하고 ResultSet 형식의 결과를 리턴합니다. |
executeUpdate(String sql) |
int |
insert, update, delete문을 실행하고 영향을 받은 행의 갯수나 0을 반환합니다. 실패한 경우 에러가 발생됩니다. |
close() |
void |
Statement의 리소스를 반납합니다. |
일단 장단점에 대하여 간단히 설명하자면 아래와 같습니다.
Statement의 장점 :
- 동적으로 SQL문을 만들수 있다.
- SQL문을 직접적으로 작성하기 때문에 쉽게 분석할 수 있다.
- sql문이 문자열로 작성되기 문자열과 같은 값을 넣기위해 작은따옴표(')등의 처리를 직접 처리해야한다.
- 잘못 작성된 경우 런타임에만(실행중 일때만) 확인할 수 있다.
- 작성된 SQL문을 재사용하기 어렵다.
Statement도 conn과 같이 클래스의 필드로 지정하고 사용하는게 편한것 같아요.
조금 전에 만든 Connection 아래에 같이 쓰도록 하겠습니다.
…
import java.sql.Connection;
import java.sql.Statement;
…
private Connection conn = null;
private Statement stmt = null;
이제 conn과 같이 Statement 인터페이스의 비어있는 private 멤버 객체(이하 stmt)를 만들었습니다.
stmt의 인스턴스는 conn으로부터 createStatement()라는 메서드를 통해 생성합니다.
insert문을 실행하는 메서드를 만들어서 알아보도록 할께요.
public void insert(String name, int temp) {
String query = "insert into test_table (name,temp) values('"+name+"', "+temp+")";//쿼리문 작성
conn = this.getConnection(); //위의 메서드로 conn을 초기화합니다.
try{
stmt = conn.createStatement(); //Connection정보를 담은 객체 conn 으로부터 Statement 인스턴스를 생성한다.
System.out.println(stmt.executeUpdate(query)); //실행할 쿼리문을 동적으로 바꿀수 있는 구조
//성공이면 0 이상, 실패면 예외가 발생합니다.
stmt.close();
//stmt는 이 메서드가 실행될때마다 생성되니까 메서드가 끝날때 자원을 반납하도록함.
conn.close(); //더이상 필요하지 않다면 conn의 자원을 반납해야합니다.
} catch(SQLException e) {
System.err.println(e.getMessage());
}
}
이 코드를 보면 대충 구조를 알 수 있습니다.
stmt는 실행 메서드(execute메서드)들을 통해 SQL문장을 실행합니다.
2.PreparedStatement
PreparedStatement는 기본적으로 Statement에서 더 추가된 기능을 사용할 수 있습니다.
위에서 본 stmt를 PreparedStatement로 알아볼께요.
PreparedStatement의 추가된 주요 메서드는 아래와 같습니다.
메서드명(파라메터) | 리턴타입 | 기능 |
execute() | boolean | sql문을 실행하고 성공하면 false가 리턴됩니다. |
executeQuery() | ResultSet | sql문을 실행하고 ResultSet 형식의 결과를 리턴합니다. |
executeUpdate() | int | insert, update, delete문을 실행하고 영향을 받은 행의 갯수나 0을 반환합니다. 실패한 경우 에러가 발생됩니다. |
set<G>(int index, <G> value) | void | 사전에 준비된 SQL문에 값을 대입합니다. |
close() | void | PreparedStatement의 자원을 반납합니다. |
stmt와 차이점은 실행 메서드들의 매개변수를 넣지않는 점입니다.
그 이유는 아래에서 알아보도록 하겠구요.
보완된 점에 대해서 알아보면 아래와 같습니다.
PreparedStatement 보완된 장점 :
- sql문장을 미리 컴파일할 수 있도록 개선되었다.
- 작은따옴표(')같은 문자열 등을 자동적으로 처리한다.
- 재사용하기 편리하다.
…
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
…
private Connection conn = null;
private Statement stmt = null;
private PreparedStatement pstmt = null;
PreparedStatement도 pstmt라고 칭하도록 하겠습니다.
pstmt의 인스턴스는 stmt와 조금 다르게 PrepareStatement(String sql)라는 메서드를 통해 생성합니다.
insert문을 실행하는 메서드를 다른 이름으로 만들겠습니다.
public void insertPrepare(String name, int temp) {
String query = "insert into test_table (name,temp) values( ? , ? )";//쿼리문 작성
conn = this.getConnection();
try{
pstmt = conn.prepareStatement(query); //Connection정보를 담은 객체 conn 으로부터 PreparedStatement 인스턴스를 생성한다.
pstmt.setString(1, name);
pstmt.setInt(2, temp);
System.out.println(pstmt.executeUpdate()); //실행할 쿼리문을 동적으로 바꿀수 있는 구조
//성공이면 0 이상, 실패면 예외가 발생합니다.
pstmt.close();
//stmt는 이 메서드가 실행될때마다 생성되니까 메서드가 끝날때 자원을 반납하도록함.
conn.close(); //더이상 필요하지 않다면 conn의 자원을 반납해야합니다.
} catch(SQLException e) {
System.err.println(e.getMessage());
}
}
이 코드에서는 stmt와 pstmt의 차이점을 알아야합니다.
처음 conn.prepareStatement의 메서드에 ?이 포함된 SQL문을 파라메터로 넘긴 후
pstmt의 set[자료형]형식의 메서드로 값을 정해줍니다.
set[자료형]의 파라메터는 int형식의 순서번호와 들어가야 할 값을 파라메터로 받아 삽입됩니다.
javadoc(자바 도움말 문서)에 있는 setString메서드를 보면 아래와 같이 나와있는데,
void java.sql.PreparedStatement.setString(int parameterIndex, String x) throws SQLException
여기서 파라메터를 보면 parameterIndex와 x를 받습니다. 만약 setString(1, "heather");라고 보면
SQL문의 첫번째 물음표에 "heather"라는 문자열을 대입하는것입니다.
여기서 알아둬야 할 것은 물음표의 순서번호가 1부터 시작한다는 것과 작은따옴표와같은 문자열 처리를 하지 않아도 된다는 것입니다.
ResultSet
이 인터페이스는 결과테이블과 테이블의 행을 가리키는 커서를 가지고있습니다.
이 커서는 처음 ResultSet에 결과를 받아 할당해주면 테이블의 첫번째 행의 이전을 가리키도록 되어있습니다.
메서드명(파라메터) | 리턴타입 | 기능 |
first() | boolean | 커서를 첫번째로 이동합니다. |
last() | boolean | 커서를 마지막으로 이동합니다. |
next() | boolean | 커서를 다음으로 이동합니다. |
previous() | boolean | 커서를 이전으로 이동합니다. |
absolute(int row) | boolean | 커서를 선택한 행으로 이동합니다. |
isFirst() | boolean | 현재 커서가 첫번째 행에 있는지 확인합니다. |
isLast() | boolean | 현재 커서가 마지막 행에 있는지 확인합니다. |
get<G>(String columnLabel) | <G> | JDBC 기본자료형과 맞는 형식의 타입으로 SQL문에서 조회된 컬럼명을 |
get<G>(int columnIndex) | <G> | JDBC 기본자료형과 맞는 형식의 타입으로 SQL문에서 조회된 컬럼의 |
close() | void | ResultSet 인스턴스를 닫습니다.(해제) |
ResultSet형식을 반환하는 executeQuery라는 메서드들 살펴보았습니다.
…
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
…
private Connection conn = null;
private Statement stmt = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
query = "SELECT * FROM test_table";
…
rs = stmt.executeUpdate(query));
num - INT
name - VARCHAR
value - INT
num |
name |
temp |
1 |
"aa" |
0 |
2 |
"bb" |
1 |
private String[] names = new String[2];
private String[] values = new String[2];
int i = 0;
while(rs.next())
{
nums[i] = rs.getInt(1); // 1번째 컬럼값은 1번으로 받아옵니다. //rs.getInt("no"); 형식으로 사용할 수 있습니다.
names[i] = rs.getString(2); // 마찬가지로 rs.getString("name"); 형식으로 사용할 수 있습니다.
values[i] = rs.getString(3); // rs.getString("value");
i++;
}
그리고 앞서 나왔던 각 컬럼값의 타입(MySQL의 자료형)과 매칭되는 Java의 자료형에 맞는 getter 메소드를 사용하여 적절하게 이용하시면
ResultSet의 기본적인 사용법은 끝입니다.
이것으로 가장 기본적인 JDBC를 사용하는 방법을 알아보았습니다.
감사합니다.
'Development > Java' 카테고리의 다른 글
[Java기초] 03.Statement와 PreparedStatement 차이 (0) | 2014.11.25 |
---|---|
[Java기초] 01.JDBC연결하기 (3) | 2014.11.25 |
[Easy Java] 01.hashCode란? (0) | 2014.11.23 |