[Java] JDBC - Statement, PreparedStatement

고동이의 IT·2021년 11월 19일
0

Java

목록 보기
36/37
post-thumbnail

Statement를 이용하는 방법

  • 간단한 쿼리문을 실행할 때 사용
package kr.or.ddit.basic;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class JdbcTest04 {

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");

			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","JHY990208","java");

			System.out.println("계좌번호 정보 추가하기");

			String sql2 = "select bank_no from bankinfo";

			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql2);


			String bankNo="";

			while(true){
				System.out.print("계좌번호: ");
				bankNo =  scan.next();
				boolean flag = true;

				while(rs.next()){

					if(rs.getString("bank_no").equals(bankNo)){
						System.out.println("중복입니다.");
						flag = false;
						break;
					}
				}
				if(flag){
					break;
				}
			}
			
			System.out.print("은행명: ");
			String bankName = scan.next();
			System.out.print("예금주명: ");
			String bankUser = scan.next();

			// '"사이에 공백 x
			String sql = "insert into bankinfo values('" + bankNo + "', '" + bankName+ "', '" + bankUser+"', sysdate)";

			// select문을 실행할때는 executeQuery()메서드를 사용하고
			// insert, update, delete문과 같이 select문이 아닌 쿼리문을 실행할때는 executeUpdate()메서드를 사용한다.
			// executeUpdate()메서드의 반환값은 작업에 성공한 레코드 수를 반환한다.
			int cnt = stmt.executeUpdate(sql);

			System.out.println("반환값: "+ cnt);
			if(cnt>0){
				System.out.println("insert 성공");
			}else{
				System.out.println("insert 실패");
			}

		} catch (SQLException e) {
			// TODO: handle exception
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//자원 반납 : 만들어진 순의 역순으로

			if(stmt!=null) try {
				stmt.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(conn!=null) try {
				conn.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
		}
	}



}

PreparedStatement를 이용하는방법

  • SQL문을 작성할 때 데이터가 들어갈 자리를 물음표(?)로 표시한다.
    String sql = "insert into bankinfo values( ? , ? , ? , sysdate)";
  • PreparedStatement 객체를 생성한다. 이때 실행할 SQL문을 매개변수에 넘겨준다.
    pstmt = conn.prepareStatement(sql); 미리쿼리문을 컴파일해서 해석하기때문에 속도가 빠르다
  • SQL문의 물음표(?)자리에 들어갈 데이터를 세팅한다.
  • 사용법) pstmt.set자료형(물음표번호, 세팅할데이터)
  • 물음표 번호는 1번부터 시작
    pstmt.setString(1, bankNo);
    pstmt.setString(2, bankName);
    pstmt.setString(3, bankUser);
    - 데이터의 세팅이 완료되면 쿼리문을 실행한다.
    int cnt =pstmt.executeUpdate();
package kr.or.ddit.basic;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class CopyOfJdbcTest04 {

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);
		Connection conn = null;
		ResultSet rs = null;
		PreparedStatement pstmt = null;
		PreparedStatement pstmt2 = null;

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");

			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","JHY990208","java");

			System.out.println("계좌번호 정보 추가하기");
			
			String bankNo ="";
			int count =0;
			do{
			System.out.print("계좌번호: ");
		    bankNo =  scan.next();
		    String sql2 = "select count(*) cnt from bankinfo where bank_no = ? ";
		    pstmt2 = conn.prepareStatement(sql2);
		    pstmt2.setString(1, bankNo);
		    
		    rs = pstmt2.executeQuery();
		    
		    if(rs.next()){ // select문의 결과가 1개의레코드일 경우 if문 사용가능
		   /* 	count = rs.getInt(1);
		    	count = rs.getInt("count(*)");*/
		    	count = rs.getInt("cnt"); // 컬럼의 alias로 설정하기
		    }
		    if(count>0){
		    	System.out.println("중복입니돵");
		    }
			}while(count>0);
			
			System.out.print("은행명: ");
			String bankName = scan.next();
			System.out.print("예금주명: ");
			String bankUser = scan.next();

			// PreparedStatement를 이용하는 방법
			// SQL문을 작성할 때 데이터가 들어갈 자리를 물음표(?)로 표시한다.
			String sql = "insert into bankinfo values( ? , ? , ? , sysdate)";

			// PreparedStatement 객체를 생성한다. 이때 실행할 SQL문을 매개변수에 넘겨준다.
			// 미리 쿼리문을 컴파일해서 해석하기때문에  속도가 빠르다
			pstmt = conn.prepareStatement(sql);
			// SQL문의 물음표(?)자리에 들어갈 데이터를 세팅한다.
			// 사용법) pstmt.set자료형(물음표번호, 세팅할데이터)
			// 물음표 번호는 1번부터 시작
			pstmt.setString(1, bankNo);
			pstmt.setString(2, bankName);
			pstmt.setString(3, bankUser);

			// 데이터의 세팅이 완료되면 쿼리문을 실행한다.
			int cnt =pstmt.executeUpdate();

			System.out.println("반환값: "+ cnt);
			if(cnt>0){
				System.out.println("insert 성공");
			}else{
				System.out.println("insert 실패");
			}

		} catch (SQLException e) {
			// TODO: handle exception
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//자원 반납 : 만들어진 순의 역순으로

			if(rs!=null) try {
				rs.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(pstmt!=null) try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(pstmt2!=null) try {
				pstmt2.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}

			if(conn!=null) try {
				conn.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
		}
	}



}

둘다 이용하는 방법

  • LPROD 테이블에 새로운 데이터를 추가하기
    • lprod_gu와 lprod_nm은 직접 입력받아서 처리하고, lprod_id는 현재의 lprod_id값 중에서 제일 큰 값보다
      1 크게한다.
    • 입력받은 lprod_gu가 이미 등록되어 있으면 다시 입력받아서 처리한다.

쿼리마다 prepareStatement만드는 이유는?

  • 왜 pstmt2? 걍 pstmt쓰면 안되는이유눙?
  • 한쿼리마다 걍 새로운 prepareStatement 만들어주는게 좋다고 합니다~

내가 한 정답

package kr.or.ddit.basic;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

/*
	LPROD 테이블에 새로운 데이터를 추가하기
	lprod_gu와 lprod_nm은 직접 입력받아서 처리하고, lprod_id는 현재의 lprod_id값 중에서 제일 큰 값보다 1 크게한다.
	
	입력받은 lprod_gu가 이미 등록되어 있으면 다시 입력받아서 처리한다.
	
*/
public class JdbcTest05 {

	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		Connection conn = null;
		ResultSet rs = null;
		PreparedStatement pstmt = null;
		Statement stmt = null;
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","JHY990208","java");
			
			String sql2 = "select lprod_gu from lprod";
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql2);
			
			String gu = "";
			
			while(true){
				System.out.println("lprod_gu를 입력하세요");
				gu = scan.nextLine();
				boolean flag = true;

				while(rs.next()){

					if(rs.getString("lprod_gu").equals(gu)){
						System.out.println("중복입니다.");
						flag = false;
						break;
					}
				}
				if(flag){
					break;
				}
			}
			
			System.out.println("lprod_nm를 입력하세요");
			String nm = scan.nextLine();
			
			
			String sql3 = "select nvl(MAX(lprod_id),0) MAX from lprod";
			rs =  stmt.executeQuery(sql3);
			int id = 0;
			if(rs.next()){
			id = rs.getInt("MAX")+1; // 컬럼의 alias로 설정하기
			 }
			
			String sql = " insert into lprod values(?, ? , ?)";
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, id);
			pstmt.setString(2, gu);
			pstmt.setString(3, nm);
			
			int cnt =pstmt.executeUpdate();
			
			System.out.println("반환값: "+ cnt);
			if(cnt>0){
				System.out.println("insert 성공");
			}else{
				System.out.println("insert 실패");
			}
			
			
		} catch (SQLException e) {
			// TODO: handle exception
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//자원 반납 : 만들어진 순의 역순으로

			if(rs!=null) try {
				rs.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(pstmt!=null) try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(conn!=null) try {
				conn.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
		}

	}

}

선생님이 한 정답

package kr.or.ddit.basic;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

/*
 	LPROD 테이블에 새로운 데이터를 추가하기
 	lprod_gu와 lprod_nm은 직접 입력받아서 처리하고, lprod_id는 현재의 lprod_id값 중에서 제일 큰 값보다 1 크게한다.
 	
 	입력받은 lprod_gu가 이미 등록되어 있으면 다시 입력받아서 처리한다.
 	
 */
public class CopyOfJdbcTest05 {

	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		Connection conn = null;
		ResultSet rs = null;
		PreparedStatement pstmt = null;
		PreparedStatement pstmt2 = null;
		Statement stmt = null;
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","JHY990208","java");
			
			// lprod_id 구하기
			String sql3 = "select nvl(MAX(lprod_id),0)+1 MAX from lprod";
			stmt = conn.createStatement();
			rs =  stmt.executeQuery(sql3);
			
			int id = 0;
			if(rs.next()){
			id = rs.getInt("MAX"); // 컬럼의 alias로 설정하기
			 }
			
			// gu 구하기
			String gu = "";
			int count = 0;
			
			do{
				System.out.println("상품 분류코드(gu)입력");
				gu = scan.nextLine();
				
				String sql2 = "select count(*) cnt from lprod where lprod_gu=?";
				pstmt = conn.prepareStatement(sql2);
				pstmt.setString(1, gu);
				
				rs = pstmt.executeQuery();
				
				if(rs.next()){
					count = rs.getInt("cnt");
				}
				
				if(count > 0){
					System.out.println("중복입니다.");
					
				}
				
			}while(count>0);
			
			System.out.println("lprod_nm를 입력하세요");
			String nm = scan.nextLine();
	
			String sql = " insert into lprod values(?, ? , ?)";
			
			// 왜 pstmt2? 걍 pstmt쓰면 안되는이유눙? 쿼리마다 prepareStatement만드는 이유는? 한쿼리마다 새로운 pstmt2 만들어주는게 좋다고 합니다~
			pstmt2 = conn.prepareStatement(sql);
			pstmt2.setInt(1, id);
			pstmt2.setString(2, gu);
			pstmt2.setString(3, nm);
			
			int cnt =pstmt2.executeUpdate();
			
			System.out.println("반환값: "+ cnt);
			if(cnt>0){
				System.out.println("insert 성공");
			}else{
				System.out.println("insert 실패");
			}
			
			
		} catch (SQLException e) {
			// TODO: handle exception
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//자원 반납 : 만들어진 순의 역순으로

			if(rs!=null) try {
				rs.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(pstmt!=null) try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(pstmt2!=null) try {
				pstmt2.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
			if(conn!=null) try {
				conn.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
		}

	}

}

JDBC 드라이버를 로딩하고 Connection객체를 생성하는 메서드로 구성된 class만들기

package kr.or.ddit.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;


// JDBC 드라이버를 로딩하고 Connection객체를 생성하는 메서드로 구성된 class만들기

public class DBUtil {
	// static 초기화 블럭
	static{
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		
		} catch (ClassNotFoundException e) {
			System.out.println("드라이버 로딩 실패");
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection(){
		try {
			return DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","JHY990208","java");
		} catch (SQLException e) {
			System.out.println("오라클 연결 실패");
			return null;
		}
	}
	
	
}
profile
삐약..뺙뺙

0개의 댓글