카테고리 없음

[JDBC] 중복코드 최소화 클래스/ execute 명령 / ResultSetMetaData 객체 / Statement객체와 PreparedStatement 객체

조가루 2023. 5. 16. 00:22

JDBC를 이용하여 insert,update,delete,select 프로그램을 각각 만들었지만, 겹치는 명령(같은 코드)이 많다.


JDBC 프로그램을 만들 때 마다, 해당 명령들은 중복 사용될 예정이기 때문에 중복을 최소화시켜주는 것이 좋다.
중복된 코드를 다른 클래스에서 따로 만들어 호출해 사용하면,코드 수정을 할 때도 번거로움을 줄일 수 있기 때문이다.


Connection 객체를 생성하여 반환하거나 JDBC 관련 객체를 매개변수로 전달받아 제거하는 기능을 메소드로 제공하는 클래스 생성

→ JDBC 프로그램 작성에 필요한 공통적인 기능을 메소드로 제공한다.
→ 코드의 중복성을 최소화 시켜 프로그램의 생산성을 높이고 유지보수의 효율성을 증가시킨다. 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class ConnectionFactory {
	//Connection 객체를 생성하여 반환하는 메소드 
	public static Connection getConnection() {
		Connection con=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String user="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			System.out.println("[에러]Connection 객체를 생성할 수 없습니다.");
		}
		return con;
	}
	
	// JDBC 관련 객체를 매개변수로 전달받아 제거하는 메소드
	
	//메소드 오버로딩 : 같은 이름의 메소드를 중복하여 정의하는 것
	public static void close(Connection con) {
		try {
			if(con != null) con.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void close(Connection con, Statement stmt) {
		try {
			if(stmt!=null) stmt.close();
			if(con != null) con.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void close(Connection con, Statement stmt, ResultSet rs) {
		try {
			if(rs!=null) rs.close();
			if(stmt!=null) stmt.close();
			if(con != null) con.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}

 

생성한 ConnectionFactory 클래스 이용하여, DEPT 테이블에 저장된 모든 부서정보를 검색하여 출력하는 JDBC 프로그램 작성

package xyz.itwill.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

//DEPT 테이블에 저장된 모든 부서정보를 검색하여 출력하는 JDBC 프로그램 작성
public class ConnectionFactoryApp {
	public static void main(String[] args) {
		Connection con=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {
			con=ConnectionFactory.getConnection();
			
			stmt=con.createStatement();
			
			String sql="select deptno,dname,loc from dept order by deptno";
			rs=stmt.executeQuery(sql);
			
			while(rs.next()) {
				System.out.println("부서번호 = "+rs.getInt("deptno")+", 부서이름 ="
						+rs.getString("dname")+", 부서 위치 = "+rs.getString("loc"));
			}
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} finally {
			ConnectionFactory.close(con, stmt, rs);
		}
	}
}


STUDENT 테이블에 저장된 정보 변경, 검색하는 JDBC 프로그램 작성 

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ExecuteApp {
	public static void main(String[] args) throws SQLException {
		Connection con=ConnectionFactory.getConnection();
		
		Statement stmt=con.createStatement();
		
		String sql1="update student set name='임걱정' where no=2000";
		int rows=stmt.executeUpdate(sql1);
		
		System.out.println("[메시지]"+rows+"명의 학생정보를 변경 하였습니다.");
		System.out.println("=============================================================");
		String sql2="select * from student order by no";
		ResultSet rs=stmt.executeQuery(sql2);
		while(rs.next()) {
			System.out.println("학번 = " + rs.getInt("no")+", 이름 = "+rs.getString("name"));
		}
		System.out.println("=============================================================");
		ConnectionFactory.close(con, stmt, rs);
	}
}

 

전달해야할 명령이 정해져 있으면 executeUpdate(),executeQuery() 명령을 사용하면 되지만  
이처럼 전달해야할 sql 명령이 명확하지 않을 때는 excute() 명령을 사용하면 된다. 

Statement.execute(String sql) : SQL 명령을 전달하여 실행하는 메소드 - boolean 반환 

  •  전달되어 실행될 SQL 명령이 명확하지 않은 경우 사용되는 메소드
  • → false 반환 : DML 명령 또는 DDL 명령을 전달하여 실행된 경우의 반환값 
    → true 반환 : SELECT 명령을 전달하여 실행된 경우의 반환값  

import java.sql.Statement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ExecuteApp  {
	public static void main(String[] args) throws SQLException {
		Connection con=ConnectionFactory.getConnection();
		
		Statement stmt=con.createStatement();
		
		int choice=1;
		String sql="";
		if(choice==1) {
			sql="update student set name='임걱정' where no=2000";	
		} else {
			sql="select * from student order by no";
		}
		boolean result=stmt.execute(sql);
		
		if(result) {//SELECT 명령이 전달되어 실행된 경우 
			//Statement.getResultSet() : Statement 객체로 전달되어 실행된 SELECT 명령의
			//처리결과를 ResultSet 객체로 반환하는 메소드 
			ResultSet rs=stmt.getResultSet();
			
			while(rs.next()) {
				System.out.println("학번 = " + rs.getInt("no")+", 이름 = "+rs.getString("name"));
			}
			
			ConnectionFactory.close(con, stmt, rs);
		} else {//DML 명령 또는 DDL 명령이 전달되어 실행된 경우 
			//Statement.getResultCount() : Statement 객체로 전달되어 실행된 DML 명령 또는 
			//DDL 명령의 처리결과를 정수값(int)로 반환하는 메소드 
			int rows=stmt.getUpdateCount();
			System.out.println("[메시지]"+rows+"명의 학생정보를 변경 하였습니다.");
			ConnectionFactory.close(con, stmt);
		}
	}
}

 

Statement.getResultCount() : Statement 객체로 전달되어 실행된 DML 명령 또는 DDL 명령의 처리결과를 정수값(int)로 반환하는 메소드 


ResultSetMetaData 객체

: 검색행(ResultSet 객체)에 대한 부가적인 정보(검색대상)가 저장되어 있다.

ResultSet.getMetaData() : ResultSetMetaData 객체를 반환하는 메소드  

ResultSetMetaData.getColumnCount() : 검색행의 컬럼 갯수를 반환하는 메소드  
ResultSetMetaData.getColumnLabel(int index) : 첨자위치(columnIndex)의 검색대상의 이름(컬럼명)을 반환하는 메소드  

ResultSetMetaData.isNullable(int columnIndex) : 첨자 위치(columnIndex)의 컬럼에 대한 Null 허용 유무값(0,1)을 반환하는 메소드  
ResultSetMetaData.columnNoNulls : NULL를 허용하지 않는 상수 = 정수값 : 0  

ResultSetMetaData.getColumnTypeName(int columnIndex) : 첨자 위치(columnIndex)의 컬럼에 대한 오라클 자료형을 반환하는 메소드  
ResultSetMetaData.getColumnDisplaySize(int columnIndex) : 첨자 위치(columnIndex) 컬럼에 대한 출력크기를 반환하는 메소드 

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

public class ResultSetMetaDataApp {
	public static void main(String[] args) throws SQLException {
		Connection con=ConnectionFactory.getConnection();
		Statement stmt=con.createStatement();
		
		String sql="select * from student order by no";
		ResultSet rs=stmt.executeQuery(sql);
		
		while(rs.next()) {
			System.out.println("학번 = " + rs.getInt("no")+", 이름 = "+rs.getString("name"));
		}
		System.out.println("================================================================");
		
		ResultSetMetaData rsmd=rs.getMetaData(); // ResultSetMetaData 객체를 반환
		
		int columnCount=rsmd.getColumnCount(); //검색행의 컬럼 갯수를 반환
		System.out.println("검색행의 컬럼 갯수 =" +columnCount);
		System.out.println("================================================================");
		for(int i=1;i<=columnCount;i++) {
			String columnLabel=rsmd.getColumnLabel(i);//index 위치의 검색대상의 이름(컬럼명)을 반환 
		
			int isNull=rsmd.isNullable(i);//index 위치의 컬럼에 대한 Null 허용 유무값(0,1)을 반환 
			
			String nullResult="NULL";
			
			if(isNull==ResultSetMetaData.columnNoNulls) {//NULL를 허용하지 않는 상수(=정수값 0)
				nullResult="NOT NULL";
			}
			
			String columnTypeName=rsmd.getColumnTypeName(i);//index 위치의 컬럼에 대한 오라클 자료형을 반
			
			int columnDisplaySize=rsmd.getColumnDisplaySize(i);//index 위치의 컬럼에 대한출력크기를 반
			
			System.out.println("컬럼의 이름= "+columnLabel);
			System.out.println("NULL 허용 유무 = "+nullResult);
			System.out.println("컬럼 자료형 = "+columnTypeName);
			System.out.println("컬럼의 출력크기 = "+columnDisplaySize);
			System.out.println("================================================================");
		}
		
		ConnectionFactory.close(con, stmt, rs);
	}
}

 


ResultSet.getRow() : ResultSet 커서가 위치한 처리행의 행번호(RowIndex)를 반환하는 메소드 

Connection.createStatement(int resultSetType, int sesultSetConcurrency)

→ 현재 접속중인 DBMS 서버에 SQL 명령을 전달하기 위한 Statement 객체를 반환하는 메소드 
→ 매개변수에 전달되는 값에 따라, Statement 객체에 의해 생성되는 ResultSet 객체의 커서에 대한 이동 방법 및 커서가 위치한 처리행의 조작 설정이 가능하다.

resultSetType : ResultSet 커서의 이동 설정 관련 값(ResultSet 인터페이스의 상수 이용)을 전달하여 설정한다.

-ResultSet 인터페이스의 상수 
→ ResultSet.TYPE_FORWARD_ONLY : ResultSet 커서를 다음행으로만 이동 가능 - 기본 
→ ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet 커서를 자유롭게 이동 가능 - 데이터베이스 변경 미반영 
→ ResultSet.TYPE_SCROLL_SENSITIVE : ResultSet 커서를 자유롭게 이동 가능 - 데이터베이스 변경 반영 

resultSetConcurrency : ResultSet 커서가 위치한 처리행의 조작 관련 속성값((ResultSet 인터페이스의 상수)을 전달
→ ResultSet.CONCUR_READ_ONLY : ResultSet 커서가 위치한 처리행 조작(행 삽입,삭제,변경) 불가능 - 기본
→ ResultSet.CONCUR_UPDATABLE : ResultSet 커서가 위치한 처리행 조작(행 삽입,삭제,변경) 가능 

ResultSet 커서를 자유롭게 이동할 수 있는 메소드

  • ResultSet.first() : ResultSet 커서를 첫번째 행으로 이동하는 메소드 
  • ResultSet.last() : ResultSet 커서를 첫번째 행으로 이동하는 메소드 
  • ResultSet.absolute(int rowIndex) : ResultSet 커서를 매개변수로 전달받은 행으로 이동하는 메소드
  • ResultSet.afterLast() : ResultSet 커서를 EOF(End Of File)로 이동하는 메소드
  • ResultSet.previous() : ResultSet 커서를 이전행으로 이동하는 메소드 
  • ResultSet.beforeFirst() : ResultSet 커서를 BOF(Before Of File)로 이동하는 메소드



    stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

    >> ResultSet 커서를 자유롭게 이동 가능하고, 행에 대한 조작이 가능

 

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ResultSetCusorApp {
	public static void main(String[] args) throws SQLException {
		Connection con=ConnectionFactory.getConnection();
		Statement stmt=con.createStatement();
		
		String sql="select * from student order by no";
		
		ResultSet rs=stmt.executeQuery(sql);
		
		while(rs.next()) {
			System.out.println(rs.getRow()+"행 : 학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name"));
		}
		System.out.println("==============================================================");
		stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
		
		sql="select * from student order by no";
		rs=stmt.executeQuery(sql);
		
		rs.first(); //ResultSet 커서를 첫번째 행으로 이동
		System.out.println(rs.getRow()+"행 : 학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name"));
		
		rs.last(); //ResultSet 커서를 마지막 행으로 이동
		System.out.println(rs.getRow()+"행 : 학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name"));
		
		rs.absolute(2); //ResultSet 커서를 매개변수로 전달받은 행으로 이동
		System.out.println(rs.getRow()+"행 : 학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name"));
		
		System.out.println("==============================================================");
		ConnectionFactory.close(con, stmt, rs);
		
	}
}

 


rs.afterLast(); //ResultSet 커서를 EOF(End Of File)로 이동 
		
while(rs.previous()) {
	System.out.println(rs.getRow()+"행 : 학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name"));
}
System.out.println("==============================================================");
rs.beforeFirst(); //ResultSet 커서를 BOF(Before Of File)로 이동 
		
while(rs.next()) {
	System.out.println(rs.getRow()+"행 : 학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name"));
}

 


		//ResultSet 커서를 자유롭게 이동 가능하고, 행에 대한 조작이 가능
        	stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
		
		//ResultSet 커서가 위치한 처리행을 조작하기 위해서는 SELECT 명령의 검색대상에 [*] 사용 불가능
		sql="select no,name,phone,address,birthday from student order by no";
		rs=stmt.executeQuery(sql);

		/*
		rs.absolute(2);
		
		//ResultSet.updateXXX(String columnLabel, XXX value) : ResultSet 객체에서 ResultSet
		//커서가 위치한 처리행의 컬럼값을 변경하는 메소드
		// => XXX는 컬럼값을 변경하기 위해 전달받기 위한 Java 자료형 
		rs.updateString("name", "임걱정");
		
		//ResultSet.updateRow() : ResultSet 객체에서 ResultSet 커서가 위치되어 변경된 
		//컬럼값이 저장된 행을 실제 테이블에 적용하여 변경 처리하는 메소드
		rs.updateRow();
		*/
		
		/*
		rs.absolute(3);
		
		//ResultSet.moveToInsertRow() : ResultSet 객체에서 ResultSet 커서가 위치한 다음행에
		//새로운 행을 삽입하고 기존행은 다음행으로 차례대로 이동 처리하는 메소드
		rs.moveToInsertRow();
		
		//새롭게 삽입된 행의 컬럼값을 변경
		rs.updateInt("no", 4000);
		rs.updateString("name", "일지매");
		rs.updateString("phone", "010-6715-9081");
		rs.updateString("address", "서울시 종로구");
		rs.updateString("birthday", "2000-12-31");
		
		//ResultSet.insertRow() : ResultSet 객체에서 삽입된 행을 실제 테이블에 적용하여
		//삽입 처리하는 메소드
		rs.insertRow();
		*/
		
		//rs.absolute(4);
		
		//ResultSet.deleteRow() : ResultSet 객체에서 ResultSet 커서가 위치한 처리행을 삭제
		//하고 실제 테이블에 적용하여 삭제 처리하는 메소드
		rs.deleteRow();
		
		rs.beforeFirst();
		while(rs.next()) {
			System.out.println(rs.getRow()+"행 : 학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name"));
		}
				
		System.out.println("==============================================================");
		ConnectionFactory.close(con, stmt, rs);
	}

Statement 객체 

: 현재 접속중인 DBMS 서버에 SQL 명령을 전달하여 실행하기 위한 기능을 제공하는 객체 

키보드로 학생정보를 입력받아 STUDENT 테이블에 삽입하고 STUDENT 테이블에 저장된 모든 학생정보를 검색하여 출력하는 JDBC 프로그램 작성

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class StatementApp {
	public static void main(String[] args) throws Exception {
    
		//키보드로 학생정보를 입력받기 위한 입력스트림을 생성 
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		
		//키보드로 학생정보를 입력받아 저장
        	System.out.println("<<학생정보 입력>>");
		System.out.print("학번 입력 >> ");
		int no=Integer.parseInt(in.readLine());
		System.out.print("이름 입력 >> ");
		String name=in.readLine();
		System.out.print("전화번호 입력 >> ");
		String phone=in.readLine();
		System.out.print("주소 입력 >> ");
		String address=in.readLine();
		System.out.print("생년월일 입력 >> ");
		String birthday=in.readLine();
		System.out.println("=====================================================================");
		//STUDNET 테이블에 키보드로 입력받은 학생정보를 삽입 처리 
		Connection con=ConnectionFactory.getConnection();
		
		Statement stmt=con.createStatement();
		
		String sql1="insert into student values("
				+no+",'"+name+"','"+phone+"','"+address+"','"+birthday+"')";
		int rows=stmt.executeUpdate(sql1);
		
		System.out.println("[결과]"+rows+"명의 학생정보를 삽입 하였습니다.");
		System.out.println("=====================================================================");
		//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 출력 처리 
		String sql2="select * from student order by no";
		ResultSet rs=stmt.executeQuery(sql2);
		
		System.out.println("<<학생정보 출력>>");
		while(rs.next()) {
			System.out.println("학번 = " + rs.getInt("no")+", 이름 = " + rs.getString("name")
				+", 전화번호 = " + rs.getString("phone")+", 주소 = " + rs.getString("address")
				+", 생년월일 = " + rs.getString("birthday").substring(0,10));
		}
		System.out.println("=====================================================================");
		ConnectionFactory.close(con, stmt, rs);
	}
}

 

Statement 객체를 사용했을 때 장점
: 하나의 Statement 객체를 사용하여 다수의 SQL 명령을 전달하여 실행하는 것이 가능하다. 

Statement 객체를 사용했을 때 단점
: SQL 명령에 Java 변수값을 포함시킬 경우 문자열 결합 기능 사용해야 하기 때문에, 문자열 결합을 이용할 경우 가독성 및 유지보수의 효율성이 감소한다.

따라서 SQL 명령에 Java 변수값을 포함시킬 경우, Statement 객체를 사용하는 것을 권장하지 않는다. 

뿐만 아니라, 문자열 결합에 이용할 때 가장 큰 문제는 InSQL 해킹 기술(값 대신 부분적인 SQL 명령을 포함시키는 해킹 기술)에 굉장히 취약하다는 것이다.


예시)
키보드로 이름을 입력받아 STUDENT 테이블에 저장된 학생정보 중 해당 이름의 학생정보를 검색하여 출력하는 JDBC 프로그램 작성 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class StatementApp {
	public static void main(String[] args) throws Exception {
	
		//키보드로 학생정보를 입력받기 위한 입력스트림을 생성 
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		
		//키보드로 학생정보를 입력받아 저장 
		System.out.print("<<학생정보 검색>> ");
		System.out.print("이름 입력 >> ");
		String name=in.readLine();
		System.out.println("=====================================================================");
		Connection con=ConnectionFactory.getConnection();
		
		Statement stmt=con.createStatement();
		
		String sql="select * from student where name='"+name+"' order by no";
		ResultSet rs=stmt.executeQuery(sql);
		
		System.out.println("<<검색결과>>");
		if(rs.next()) {
			do {
				System.out.println("학번 = " + rs.getInt("no")+", 이름 = " + rs.getString("name")
				+", 전화번호 = " + rs.getString("phone")+", 주소 = " + rs.getString("address")
				+", 생년월일 = " + rs.getString("birthday").substring(0,10));
			} while (rs.next());
		} else {
			System.out.println("검색된 학생정보가 없습니다.");
		}
		System.out.println("=====================================================================");
		ConnectionFactory.close(con, stmt, rs);
	}
}

 

InSQL 해킹 기술에 의해 원치 않는 결과값 반환

이처럼값을 입력하지 않고, 부분적인 SQL 명령을 입력하면 잘못된 결과를 제공한다는 것이 Statement 객체의 최대 단점이다.


PreparedStatement 객체

  • 현재 접속중인 DBMS 서버에 SQL 명령을 전달하여 실행하기 위한 기능을 제공하는 객체 
  • Statement를 부모로 가지고 있는 자식 객체


장점

: InParameter를 사용하여 SQL 명령에 Java 변수값을 문자값으로 포함하여 사용이 가능하다.
→ InParameter를 사용하여 가독성이 향상되고 유지보수의 효율성이 증가한다.
 InSQL 해킹 기술을 무효화 처리 - InParameter로 전달받은 사용자 입력값은 SQL 명령에서 무조건 문자값으로 처리

단점

 : 하나의 PreparedStatement는 저장된 하나의 SQL 명령만 전달하여 실행이 가능하다.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class PreparedStatementApp {
	public static void main(String[] args) throws Exception{
		//키보드로 학생정보를 입력받아 STUDENT 테이블에 삽입하고 STUDENT 테이블에 저장된 
		//모든 학생정보를 검색하여 출력하는 JDBC 프로그램 작성 	
		
		//키보드로 학생정보를 입력받기 위한 입력스트림을 생성 
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
				
		//키보드로 학생정보를 입력받아 저장
		System.out.println("<<학생정보 검색>> ");
		System.out.print("학번 입력 >> ");
		int no=Integer.parseInt(in.readLine());
		System.out.print("이름 입력 >> ");
		String name=in.readLine();
		System.out.print("전화번호 입력 >> ");
		String phone=in.readLine();
		System.out.print("주소 입력 >> ");
		String address=in.readLine();
		System.out.print("생년월일 입력 >> ");
		String birthday=in.readLine();
		System.out.println("=====================================================================");
		//STUDNET 테이블에 키보드로 입력받은 학생정보를 삽입 처리 
		Connection con=ConnectionFactory.getConnection();
		
		//Connection.prepareStatement(String sql) : Connection 객체로부터 SQL 명령이 저장된 
		//PreparedStatement 객체를 반환하는 메소드 
		// => PrepareStatement객체에 저장되는 SQL 명령에는 ?(InParameter) 기호 사용 
		//InParameter : Java 변수값을 제공받아 SQL 명령의 문자값으로 표현하기 위한 기호 
		// => 반드시 모든 InParameter에 Java 변수값을 전달받아 완전한 SQL 명령을 완성시켜 줘야 한다.
		String sql="insert into student values(?,?,?,?,?)"; //불완전한 SQL 명령 
		PreparedStatement pstmt=con.prepareStatement(sql);
		//PreparedStatement.setXXX(int parameterIndex, XXX value)
		// => PreparedStatement 객체에 저장된 SQL 명령의 InParameter에 Java 변수값을 전달하는 메소드 
		// => XXX : InParameter에 전달하기 위한 값에 대한 Java 자료형
		// => parameterIndex : InParameter의 위치값(첨자) - 1부터 1씩 증가되는 정수값 
		// => 반드시 모든 InParameter에 Java 변수값을 전달받아야지만 완전한 SQL 명령을 완성할 수 있다.
		pstmt.setInt(1, no);
		pstmt.setString(2, name);
		pstmt.setString(3, phone);
		pstmt.setString(4, address);
		pstmt.setString(5, birthday);
		
		//PreparedStatement.executeUpdate() : PreparedStatement 객체에 저장된 DML 명령을 
		//전달하여 실행하고 조작행의 갯수를 정수값(int)로 반환하는 메소드 
		int rows=pstmt.executeUpdate();
		
		System.out.println("[결과]"+rows+"명의 학생정보를 삽입 하였습니다.");
		System.out.println("=====================================================================");
		//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 출력 처리
		String sql2="select * from student order by no";
		pstmt=con.prepareStatement(sql2);
		
		//PreparedStatement.executeUpdate() : PreaparedStatement 객체에 저장된 SELECT 명령을
		//전달하여 실행하고 모든 검색행이 저장된 Result 객체를 반환하는 메소드
		ResultSet rs=pstmt.executeQuery();
		
		System.out.println("<<학생정보 출력>>");
		while(rs.next()) {
			System.out.println("학번 = " + rs.getInt("no")+", 이름 = " + rs.getString("name")
				+", 전화번호 = " + rs.getString("phone")+", 주소 = " + rs.getString("address")
				+", 생년월일 = " + rs.getString("birthday").substring(0,10));
		}
		System.out.println("=====================================================================");
		ConnectionFactory.close(con, pstmt, rs);

	}
}


키보드로 이름을 입력받아 STUDENT 테이블에 저장된 학생정보 중 해당 이름의 학생정보를 검색하여 출력하는 JDBC 프로그램 작성 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class PreparedStatementApp {
	public static void main(String[] args) throws Exception{
		//키보드로 학생정보를 입력받기 위한 입력스트림을 생성 
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
				
		//키보드로 학생정보를 입력받아 저장 
		System.out.println("<<학생정보 검색>> ");
		System.out.print("이름 입력 >> ");
		String name=in.readLine();
		System.out.println("=====================================================================");
		Connection con=ConnectionFactory.getConnection();
		
		String sql="select * from student where name=? order by no"; 
		PreparedStatement pstmt=con.prepareStatement(sql);
		pstmt.setString(1, name);
		
		ResultSet rs=pstmt.executeQuery();
		
		System.out.println("<<검색 결과>>");
		if(rs.next()) {
			do {
				System.out.println("학번 = "+rs.getInt("no")+", 이름 = "+rs.getString("name")
					+", 전화번호 = "+rs.getString("phone")+", 주소 = "+rs.getString("address")
					+", 생년월일 = "+rs.getString("birthday").substring(0, 10));
			} while(rs.next());
		} else {
			System.out.println("검색된 학생정보가 없습니다.");
		}
		System.out.println("==============================================================");
		ConnectionFactory.close(con, pstmt, rs);
	}
}

 

InParameter로&nbsp;전달받은&nbsp;사용자&nbsp;입력값은&nbsp;SQL&nbsp;명령에서&nbsp;무조건&nbsp;문자값으로&nbsp;처리한다.