JDBC: 쿼리의 효율적 사용(PreparedStatement)

0

JDBC

목록 보기
2/4
post-thumbnail

Statement

createTable에는 다음과 같이 Statement를 사용했다.

	// 테이블 생성 
	public boolean createTable() throws SQLException {
		boolean flag = false;
		
		String sql = "create table toys (";
				sql+= "No int auto_increment primary key not null, ";
				sql+= "name varchar(20) not null, ";
				sql+= "manufacturing varchar(20) not null, ";
				sql+= "price int not null ";
				sql+= ")";
				
		Connection con = ConnectionManager.getConnection();
		Statement stmt = con.createStatement();
		int affectedCount = stmt.executeUpdate(sql);
		
		System.out.println("쿼리의 반환값은 :"+affectedCount);
		
		if(affectedCount == 0) {
			flag = true;
		}
		
		return flag;
	}//createTable()

다른 테이블을 또 만들기 위해서는 이 코드를 여러 번 수정해야할 것이다.
또, INSERT문을 여러 번 실행한다고 가정했을 때 코드가 중복되고 내용이 많아지다보면 파일 내에서 찾기도 힘들 것이다.

PreparedStatement

특정 쿼리를 수행할 때, 원하는 부분만을 매개변수로 하여 코드를 재사용할 수 있게 한다면 굉장히 효과적일 것이다.

재사용은 PreparedStatement로 구현한다.
다음과 같이 사용한다.

	// Toy 테이블에 레코드 insert
	public boolean insertToy(String name, String manufacturing, int price) throws SQLException {
		boolean flag = false;
		
		String sql = "insert into toys (name, manufacturing, price) ";
				sql+= "values(";
				sql+= "?, ";
				sql+= "?, ";
				sql+= "? ";
				sql+= ");";
				
		Connection con = ConnectionManager.getConnection();
		PreparedStatement pstmt = con.prepareStatement(sql);
		
		pstmt.setString(1, name);			// 첫 번째 물음표에 매개 변수로 받은 name 넣기 
		pstmt.setString(2, manufacturing);	// 두 번째에는 매개 변수로 받은 manufacturing 넣기
		pstmt.setInt(3, price);				// 세 번째에는 매개 변수로 받은 price 넣기
		
		int affectedCount = pstmt.executeUpdate();
		
		if(affectedCount > 0) {
			flag = true;
		}
		
		pstmt.close();	// 통로 닫기
		con.close();	// 연결 닫기 
		
		return flag;
	}//insertToy()

statement와 다른 점은

  1. 일단 당연히 .preparedStatement()를 사용한다는 것이다
  2. 쿼리를 보면 알 수 있지만, 파라미터로 받을 값을 ? 기호로 지정한다는 것이다
  3. ?에 들어갈 값은
    .setString(? 기호의 순서, 넣어줄 값)
    .setInt(? 기호의 순서, 넣어줄 값)
    위와 같은 방식이다
    다양한 자료 타입으로 set...(? 순서, 값)을 사용할 수 있다

하나의 쿼리를 정해두고, 원하는 값을 변경해가면서 반복하여 쓸 수 있게 된다.

저번 코드와 또 다른 점은 .close()를 사용한 점이다.
Connection()Statement()를 사용한 후에는 꼭 닫아준다!

위의 쿼리를 Main에서 사용한다면 아래와 같다.

package prac;

import java.sql.SQLException;

public class JdbcMain {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JdbcMain main = new JdbcMain();
		
		//main.createTable();
		main.insertToy("watergun", "LockheedMatin", 1500000);
	}//main();

	
	// 테이블 생성하기 
	public void createTable() {
		BusinessLogic bl = new BusinessLogic();
		try {
			boolean flag = bl.createTable();
			if(flag) {
				System.out.println("테이블 생성에 성공했습니다");
			} 
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println("테이블 생성에 실패했습니다");
			e.printStackTrace();
		}
	}// getTable();
	
	
	// 레코드 입력하기 
	public void insertToy(String name, String manufacturing, int price) {
		BusinessLogic bl = new BusinessLogic();
		try {
			boolean flag = bl.insertToy(name, manufacturing, price);
			if(flag) {
				System.out.println("레코드 삽입에 성공했습니다");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println("레코드 삽입에 실패했습니다");
			e.printStackTrace();
		}
	}// insertToy();
	
	
}
>> 실행 결과
Connected...
레코드 삽입에 성공했습니다

MariaDB [jdbc]> select * from toys;
+----+----------+---------------+---------+
| no | name     | manufacturing | price   |
+----+----------+---------------+---------+
|  1 | watergun | LockheedMatin | 1500000 |
+----+----------+---------------+---------+
1 row in set (0.001 sec)

main.insertToy("watergun", "LockheedMatin", 1500000);
이 부분에서 insertToy()를 호출하여 실행한다.

preparedStatement는 같은 형식의 쿼리를 실행하는 Java 코드를 재활용하여 사용할 수 있게 해준다.

매우. 매우. 매우.
편리하다!

0개의 댓글