JDBC異常處理和資源釋放問題

以前咱們在介紹JDBC加載註冊驅動的時候說過有三種方式,是哪三種方式呢?咱們再來看看mysql

Class.forName("com.mysql.jdbc.Driver");
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
以上三種方式均可以實現JDBC的驅動加載註冊,這裏咱們推薦使用Class.forName(「com.mysql.jdbc.Driver」);另外DriverManager.registerDriver(new com.mysql.jdbc.Driver());其實能夠直接寫成new com.mysql.jdbc.Driver();這裏咱們瞭解就好,大可沒必要深究,除非有必要!程序員

今天咱們來講說JDBC鏈接數據庫的異常的正確處理,還記得以前咱們是怎麼處理的嗎?沒錯,咱們直接給拋出了,代碼是這個樣子滴!
@Test
      public void ddlAndExceptionTest() throws Exception{
            String sql = "CREATE TABLE `t_student` (`id` bigint(10)  DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;";sql

            //加載註冊驅動
            Class.forName("com.mysql.jdbc.Driver");數據庫

            //獲取鏈接對象
            Connection connection =  DriverManager.getConnection("jdbc:mysql:///jdbcdemo", "root",  "123456");.net

            //建立獲取語句對象
            Statement st = connection.createStatement();對象

            //執行SQL語句
            st.executeUpdate(sql);blog

            //釋放資源
            st.close();
            connection.close();資源

      }
咱們這裏直接throws Exception了,其實這樣是不妥的,那正確的異常處理方式是什麼呢?在此以前咱們應該知道處理異常咱們都用try catch的,有時候也配合finally一塊兒使用,在處理JDBC鏈接數據庫的異常時咱們須要着重瞭解的還有資源釋放的問題,就是那個xxx.close,下面咱們一步步結合代碼來講get

首先咱們看須要處理異常的代碼io

諸如此類的代碼異常咱們都將它使用try catch包裹
 //加載註冊驅動
            try {
                  Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }
而後將catch中的異常類型改成Exception,而後繼續寫代碼,完成JDBC鏈接數據庫的後續步驟,代碼如

 try {
                  //加載註冊驅動
                  Class.forName("com.mysql.jdbc.Driver");
                  //獲取鏈接對象
                  Connection connection =  DriverManager.getConnection("jdbc:mysql:///jdbcdemo","root","123456");
                  //建立或者獲取語句對象
                  Statement statement = connection.createStatement();
                  //執行sql語句
                  statement.executeUpdate(sql);
                  //釋放資源
                  statement.close();
                  connection.close();

            } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }
到這裏咱們就已經將異常作了相應的處理,可是這裏面還有個很大的問題那就是資源釋放的問題,也就是說目前釋放資源的代碼放在那裏是不妥的,若是以前代碼出現個什麼意外,那麼資源就沒法釋放了,可能有人說了,爲何這個資源必需要釋放呢?

那麼咱們就來講道說道這個資源爲何必須釋放呢? 
咱們先來看這個Connection,這傢伙是數據庫的鏈接對象,你可要知道在JDBC中Connection這個資源是很是稀有的,使用以後必須立刻釋放,我記得在哪看過關於這塊釋放資源的一個原則好像是「晚點用,早點放」,嗯,大概就是這個意思,總之在使用的過程當中只有用到的時候纔去建立這個對象,使用以後也要記得立馬釋放。

所以,爲了保證資源的必須釋放,咱們該怎麼作呢?沒錯,咱們能夠將釋放資源的代碼放到finally裏,這樣就能夠保證不管以前的代碼怎樣,釋放資源的代碼一定執行。

這樣代碼就變成了如今這個樣子了
 @Test
      public void testException(){
            String sql = "CREATE TABLE `t_one` (`id` bigint(10) DEFAULT  NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
            Statement statement = null;
            Connection connection = null;
            try {
                  //加載註冊驅動
                  Class.forName("com.mysql.jdbc.Driver");
                  //獲取鏈接對象
                  connection =  DriverManager.getConnection("jdbc:mysql:///jdbcdemo","root","123456");
                  //建立或者獲取語句對象
                  statement = connection.createStatement();
                  //執行sql語句
                  statement.executeUpdate(sql);
                  //釋放資源
                  statement.close();
                  connection.close();

            } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            } finally {
                  //釋放資源
                  try {
                        statement.close();
                        connection.close();
                  } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                  }

            }


      }
到了這一步,你看看是否是就能夠了呢?其實否則,這裏面仍是不行,哪裏不行呢?咱們來看,假如在connection沒有來得及賦值的時候出現了意外,這樣就會直接執行finally裏面的代碼,這樣就會致使一個空對象調用close,就會引發新的異常致使程序崩潰,對於statement依然如此,所以,咱們須要進行判空!

所以finally裏面釋放資源的代碼應該這樣寫


finally {
                  //釋放資源
                  if (statement!=null) {
                        try {
                              statement.close();
                        } catch (SQLException e) {

                              e.printStackTrace();
                        }finally {
                              if (connection!=null) {
                                    try {
                                          connection.close();
                                    } catch (SQLException e) {

                                          e.printStackTrace();
                                    }
                              }
                        }
                  }

            }
所以正確完整的代碼以下


 //正確處理JDBC的異常
      @Test
      public void testHandleException(){

            Connection con = null;
            Statement st = null;
            String sql = "CREATE TABLE `t_new1` (`id` bigint(10) DEFAULT  NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;";

            //異常標準代碼格式結構
            try{

                  //這裏存放可能出現異常的代碼
                  //加載註冊驅動
                  Class.forName("com.mysql.jdbc.Driver");
                  //獲取鏈接對象
                  con =  DriverManager.getConnection("jdbc:mysql:///jdbcdemo","root","123456");
                  //獲取鏈接語句
                  st = con.createStatement();
                  //執行sql語句
                  st.executeUpdate(sql);

            }
            catch (Exception e) {

                  e.printStackTrace();             }finally {                   //釋放資源、                   if (st!=null) {                         try {                               st.close();                         } catch (Exception e2) {                               // TODO: handle exception                         }finally {                               if (con!=null) {                                     try {                                           con.close();                                     } catch (Exception e3) {                                           // TODO: handle exception                                     }                               }                         }                   }             }            } ---------------------  做者:一個自學的程序員  來源:CSDN  原文:https://blog.csdn.net/sinat_33921105/article/details/79497823  版權聲明:本文爲博主原創文章,轉載請附上博文連接!

相關文章
相關標籤/搜索