JDBC:JDBCリソース解放の詳細


前のブログではjdbcの基本的な使い方を紹介しましたが、コードの中には次のようなものがあります.
public static void main(String[] args) {  
        Connection conn = null;  
        Statement state = null;  
        ResultSet set = null;  
        try {  
            //         
            DriverManager.registerDriver(new Driver());  
            //            
             conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "");  
            //         
             state= conn.createStatement();  
            //         sql    
             set=state.executeQuery("select * from emp");  
            while(set.next()){  
                System.out.println(set.getString("name"));  
            }  
        } catch (SQLException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }finally{  
            try {  
                set.close();  
                state.close();  
                conn.close();  
            } catch (SQLException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
  
        }  
    }  
これらのコードの最後に3つのXXが表示されます.closeはリソースを解放しますが、このようにリソースを解放するのは問題があります.前のブログは入門したので、複雑すぎる問題を検討せず、jdbcの使い方に重点を置きました.
では、このブログでは、リソースを解放する方法について説明します.
jdbcではConnectionは非常に希少なリソースであり、使用が完了するとすぐに解放され、さらには「遅延、早期解放」の原則で使用されるべきである.つまり、使用中にできるだけ使用しなければならないときにConnectionを作成し、使用が完了するとすぐに解放を閉じるべきである.
最初は
  Connection conn = null;  
        Statement state = null;  
        ResultSet set = null;  
は3つの空の値を定義して、下に実行すると、まだ3つの変数に値を割り当てるまで実行していないのに異常を投げて、この時プログラムはcatchでfinallyの中の文を実行しますが、この時set、state、connはすべて空で、空のオブジェクト呼び出し方法はnullpointexceptionを投げ出して、この時プログラム全体がクラッシュしました.だから閉鎖する前に空を判断しなければなりません.
空の判定を行ってからリソースを閉じるのは問題がありますが、最後にリソースを閉じるときを見てください.
try {  
                set.close();  
                state.close();  
                conn.close();  
            } catch (SQLException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
はすべての閉じた文を同じtryブロックに書き、前の管比喩文が異常に投げられると、後の閉じた文は実行できないので、このように書くことはできません.閉じた文ごとにtryブロックを1つあげます.最後に、リソースが解放されることを保証するために、各クローズ文の後ろにfinallyを追加し、finallyでクローズするリソースに空の値を割り当てます.これにより,クローズ中に異常を投げてもタイムリーにクローズできないが,付与値が空であるため,そのリソースを引用せず,ごみ回収時に回収できる.
以下は厳格で正確なクローズリソースの書き方であり、他のクローズリソースについてもこの書き方を参考にすることができます.
package com.javy.jdbc;

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

import com.mysql.jdbc.Driver;

public class JdbcDemo1 {

	public static void main(String[] args) {
		Connection conn = null;
		Statement state = null;
		ResultSet set = null;
		try {
			//        
			DriverManager.registerDriver(new Driver());
			Class.forName("com.mysql.jdbc.Driver");
			//        
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "");
			//        
			state = conn.createStatement();
			//          sql  
			set = state.executeQuery("select * from emp");
			while (set.next()) {
				System.out.println(set.getString("name"));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				conn.close();

			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				conn = null;
			}
			try {
				set.close();

			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				set = null;
			}

			try {
				state.close();

			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				state = null;
			}

		}
	}

}