[JDBC] 중복코드 최소화 클래스/ execute 명령 / ResultSetMetaData 객체 / Statement객체와 PreparedStatement 객체
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);
}
}
이처럼값을 입력하지 않고, 부분적인 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);
}
}