2/23(火)JDBC(3)/Service(1)


6.会員はJDBCを脱退する


1) View - MemberMenu

Prepared Statement


StatementとPreparedStatementの違い


(1) Statement


:同じ場合、完了したsql文を直接実行するオブジェクト
(sql文を完了する形で=ユーザーが入力した値が入力されている必要があります)
Connectionオブジェクトを使用したStatementオブジェクトの作成
: stmt = conn.createStatement();
executeXXXメソッドを使用してsql文を渡し、stmtを実行します.executeXXX(sql);

(2) PreparedStatement


:同じ場合、すぐに実行する必要なく、sql文を一時的に保持できます.
(==未完了のsql文を一時的に保持できます!)
ただし、ユーザーが入力した値に十分なスペース(?==フォルダ)があることを確認するだけでよい!
このsql文を実行する前に、完了形式で作成して実行するだけです.
Connectionオブジェクトを使用してPreparedStatementオブジェクトを作成します(ただし、sql文を使用して作成します)
: pstmt = conn.prepareStatement(sql);
現在含まれているsql文が未完了のsql文である場合、空白のスペースを埋めるプロセス
: pstmt.setString(1、「実績値」);or pstmt.setInt(2,実績);
executeXXXメソッドを使用して実行するだけで、結果=pstmtになります.executeXXX();
  • JDBC処理手順
    1)JDBCドライバ登録:DBMSが提供するクラスを登録する
    2)接続の作成:接続するDB情報を入力し、DBに接続して作成する
    3 1)Prepare Statementの作成:Connectionオブジェクトを使用して作成(最初はsql文を使用して作成)
    [3 2)未完了のsql文を完了形式で埋め込むプロセス]
    4,5) pstmt.executeXXX(); => パラメータsqlを置くことができません!!
    以降の順序は同じです.
  • <예시>
    <Stmt 방식>
    int result = 0;			// 처리된 결과(처리된 행수)를 담아줄 변수
    Connection conn = null; // 접속된 DB의 연결정보를 담는 변수
    Statement stmt = null;	// sql문 실행 후 결과를 받기 위한 변수
    		
    // 실행할 sql문(완성형태로 만들어둘것!!) => 끝에 세미콜론 있으면 안됨!!
    // INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, 
    			    'XXX', 'XXXX', 'XXX', 'X', XX, 'XXXX', 'XXXX', 'XXXX', 'XXXX', SYSDATE)
    
    String sql = "INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, "
    				   	+ "'" + m.getUserId() 	+ "', "
    				   	+ "'" + m.getUserPwd() 	+ "', "
    				   	+ "'" + m.getUserName() + "', "
    				   	+ "'" + m.getGender() 	+ "', "
    				   	+ "'" + m.getAge()	+  ", "
    				   	+ "'" + m.getEmail()	+ "', "
    				   	+ "'" + m.getPhone()	+ "', "
    				   	+ "'" + m.getAddress() 	+ "', "
    				   	+ "'" + m.getHobby()	+ "', SYSDATE)";
                        
     try {
    // 1) jdbc driver 등록
    Class.forName("oracle.jdbc.driver.OracleDriver"); 
    			
    // 2) Connection 객체 생성 (DB와 연결 --> url, 계정명, 비밀번호)
    conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
    			
    // 3) Statement 객체 생성
    stmt = conn.createStatement();
    			
    // 4, 5) DB에 완성된 sql문 전달하면서 실행 후 결과(처리된행수) 받기
    result = stmt.executeUpdate(sql);
    
    
    <Pstmt 방식>
    int result = 0;		// 처리된 결과(처리된 행수)를 담아줄 변수
    Connection conn = null; // 접속된 DB의 연결정보를 담는 변수
    Statement stmt = null;	// sql문 실행 후 결과를 받기 위한 변수
    		
    // 실행할 sql문(완성형태로 만들어둘것!!) => 끝에 세미콜론 있으면 안됨!!
    // INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, 
    			   'XXX', 'XXXX', 'XXX', 'X', XX, 'XXXX', 'XXXX', 'XXXX', 'XXXX', SYSDATE)
    String sql = "INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, ?, ?, ?, ?, ?, ?, ?, ?, ?, SYSDATE)";
    
    
    try {
    			```
    // 1) jdbc driver 등록
    Class.forName("oracle.jdbc.driver.OracleDriver"); 
    
    			
    // 2) Connection 객체 생성 (DB와 연결 --> url, 계정명, 비밀번호)
    conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
    			
    // 3_1) Statement 객체 생성
    pstmt = conn.prepareStatement(sql);
    			
    // 3_2) 내가 담은 sql문이 미완성된 sql문일 경우 값 채우기 (pstmt.setXXX(홀더순번, 대체할 값);)
    //      pstmt.setString(홀더순번, 대체할 값); 
    --> '대체할 값'(양 옆에 홑따옴표 붙어서 들어감-> 즉, 따로 적어줄 필요 없음)
    //      pstmt.setInt(홀더순번, 대체할 값); 
    --> 대체할 값(양 옆에 홑따옴표 안 들어감)
    
    	pstmt.setString(1, m.getUserId());
    	pstmt.setString(2, m.getUserPwd());
    	pstmt.setString(3, m.getUserName());
    	pstmt.setString(4, m.getGender());
    	pstmt.setInt(5, m.getAge());
    	pstmt.setString(6, m.getEmail());
    	pstmt.setString(7, m.getPhone());
    	pstmt.setString(8, m.getAddress());
    	pstmt.setString(9, m.getHobby());
        
    // 4, 5) DB에 완성된 sql문 전달하면서 실행 후 결과(처리된행수) 받기
    result = pstmt.executeUpdate(); 
    PreparedStatementの最大の欠点
    :完了したsql文の形式が見えません.

    Service


    :Daoの役割が多すぎるので、業務を割り当てます!

    JDBCTemplate class


    :JDBCプロセスで繰り返し使用される構文を各メソッドとして定義します.
    汎用テンプレートを使用して繰り返し使用します.

  • Connection、Statement、Resultset、トランザクションクラス

  • このようなすべてのメソッドは静的メソッド(メモリ領域で共有される概念)です.

  • モノトーンモードモノトーンモード:メモリ領域を1回繰り返し使用するコンセプト
  • (1)DBに接続されたConnectionオブジェクトを作成して戻す方法

    public static Connection getConnection() {
    		
    	Connection conn = null;
    		
    	try {
    		Class.forName("oracle.jdbc.drvier.OracleDriver");
    		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");	
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    		return conn;
    	}

    (2)JDBCに渡されたオブジェクトを返却する方法


    finally-conn.close()またはstmt.close()の定式化
    もともとこの過程ではなかった.
    <올바르지 않은 예시>
    finally {
    		
    	pstmt.close();
    	conn.close();
    }
    この過程です!
    <정석>
    
    try {
    	if((p)stmt != null && !(p)stmt.isClosed()) {
    		(p)stmt.close();
    	}
        } catch (SQLException e) {
    	e.printStackTrace();
        	}
    
    try {
    	if(conn != null && !conn.isClosed()) {
    		conn.close();
    	}
         } catch (SQLException e) {
    		e.printStackTrace();
    	}
    もともとこのようにして資源を返還するのです.
    どうしたんですか.条件はありますか.
    ->前のsuconnまたはstmtで実行中にエラーが発生してcatchが発生した場合、
    conn,stmt値はnullに初期化される.
    これからcloseの文法が正常に働かないから!
    <Connection 객체 전달받아서 반납시켜주는 메소드>
    	
    public static void close(Connection conn) {
    	try {
    		if(conn != null && !conn.isClosed()) {
    			conn.close();
    		}
    	} catch (SQLException e) {
    		e.printStackTrace();
    	  }
    }
    	
    <Statement 객체 전달받아서 반납시켜주는 메소드>
    public static void close(Statement stmt) {
    	try {
    		if(stmt != null && !stmt.isClosed()) {
    			stmt.close();
    		}
    	} catch (SQLException e) {
    		e.printStackTrace();
    	  }
    }
    
    <ResultSet 객체 전달 받아서 반납시켜주는 메소드>
    public static void close(ResultSet rset) {
    	try {
    		if(rset != null && !rset.isClosed()) {
    			rset.close();
    		}
    	} catch (SQLException e) {
    		e.printStackTrace();
    	  }
    }

    (3)入力したConnectionオブジェクトを使用してトランザクションを処理する方法

    <Commit: 전달받은 Connection 객체를 가지고 commit 시켜주는 메소드>
    	
    	public static void commit(Connection conn) {
    		
    		try {
    			if(conn != null && !conn.isClosed()) {
    				conn.commit();
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    	
    <Rollback: 전달받은 Connection 객체를 가지고 rollback 시켜주는 메소드>
    	public static void rollback(Connection conn) {
    		try {
    			if(conn != null && !conn.isClosed()) {
    				conn.rollback();
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}