天天看點

JDBC和異常總結及常見使用

JDBC

-一、JDBC連接配接過程

01.注冊驅動

<code>Class.forName(</code><code>"oracle.jdbc.driver.OracleDriver"</code><code>);</code>

02.擷取連接配接

<code>Connection</code> <code>conn = DriverManager.getConnection(</code><code>"jdbc:oracle:thin:@10.0.19.252:1521:orcl"</code><code>,</code><code>"itxy"</code><code>,</code><code>"itxy"</code><code>);</code>

-二、JDBC 常用接口

    JDBC :   sun提供的通路資料庫的規範

    這套規範用于高速資料庫廠商,通過何種方式通路他們的資料庫

01.java.sql 接口 Connection

    sun的JDBC是一套接口規範,沒有提供實作 (JDBC的接口實作,隻能由各個資料庫廠商自己實作) 

02.java.sql 

    接口 Statement   用于執行靜态 SQL 語句并傳回它所生成結果的對象。

java.sql 

   接口 PreparedStatement   表示預編譯的 SQL 語句的對象。 

    注意:開發的時候首先 PreparedStatement 

          原因: 1. 預編譯的 SQL 語句的對象運作速度快

                 2. 安全 (可以防止SQL注入攻擊)

03.java.sql 接口 ResultSet

    表示資料庫結果集的資料表,通常通過執行查詢資料庫的語句生成。

<code>  ResultSet</code> 對象具有指向其目前資料行的光标。最初,光标被置于第一行之前。<code>next</code> 方法将光标移動到下一行;因為該方法在 <code>ResultSet</code> 對象沒有下一行時傳回 <code>false</code>,是以可以在 <code>while</code> 循環中使用它來疊代結果集。

    預設的 <code>ResultSet</code> 對象不可更新,僅有一個向前移動的光标。是以,隻能疊代它一次,并且隻能按從第一行到最後一行的順序進行。

-三、JDBC使用常見異常

java.lang 

類 Class&lt;T&gt;

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver2   

    資料庫驅動未加載成功

java.sql.SQLException: The Network Adapter could not establish the connection

     資料庫連接配接串配置錯誤

java.sql.SQLException: ORA-01017: invalid username/password; logon denied

      通路資料庫的使用者名或密碼錯誤

注:

JDBC 與 

     UPDATE 表名 SET 字段名1=表達式1, 字段名2=表達式2, ... WHERE 條件;

     重點: 傳回值,int (update語句影響的記錄條數) 

    但是如果jdbc與insert就不用看傳回值,如果有異常,則表示插入失敗。

異常總結

 1. 異常的處理順序,一定是子類異常處理在前,父類異常處理在後

<code>try</code> <code>{</code>

<code>    </code><code>biz.deleteStudent(</code><code>"s002"</code><code>); </code>

<code>    </code><code>System.out.println(</code><code>"删除完畢!"</code><code>);</code>

<code>} </code><code>catch</code> <code>(SQLIntegrityConstraintViolationException e) {</code>

<code>            </code> 

<code>} </code><code>catch</code> <code>(Exception e) {</code>

<code>    </code><code>e.printStackTrace();</code>

<code>    </code><code>System.out.println(</code><code>"系統異常,請檢查"</code><code>);</code>

<code>}  </code>

  2. 在三層架構中,每層都可能出現異常,但是隻有UI層采用最終的異常顯示的決定權。

     其它層可以捕獲異常,但是處理後需要再次抛出!

  3. 非托管資源(不受GC管理的資源),一定要在finally中釋放,放在資源洩漏;

    不受GC管理的資源:如資料連接配接Connection , 必須要用close()方法釋放

    還有IO流的釋放,也必須使用close()

<code> </code><code>try</code> <code>{</code>

<code>                </code> 

<code>}</code><code>finally</code><code>{</code>

<code>    </code><code>dao.closeConnection();</code>

<code>}</code>

  4. 自定義異常

<code>public</code> <code>class</code> <code>HavaSonRecordsException </code><code>extends</code> <code>Exception{</code>

<code>    </code> 

<code>    </code><code>public</code> <code>HavaSonRecordsException(String msg){</code>

<code>        </code><code>super</code><code>(msg);</code>

<code>    </code><code>}</code>

 5. java.lang 類 Throwable

    直接已知子類: 

    Error, Exception 

    Error 是 Throwable 的子類,用于訓示合理的應用程式不應該試圖捕獲的嚴重問題。

    注意: Error無需用try catch  

    Error異常舉例: 如記憶體越界、記憶體溢出

6. try catch   是可以嵌套使用的

7.隻有try,沒有catch  

<code>  </code><code>try</code> <code>{</code>

<code>    </code><code>dao.updateStuState(</code><code>0</code><code>, sno);               </code>

<code>    </code><code>//釋放IO流的句柄</code>

<code>    </code><code>System.out.println(</code><code>"io資源釋放"</code><code>);</code>

8. checked Exception 與 unChecked Exception(Runtime Exception)

checked Exception(特點:在編譯期可以明确異常的可能發生的位置,而且必須要捕獲它):

    ClassNotFoundException

    SQLException

    Runtime Excepiton (編譯期無法檢查到這個異常,隻有在程式運作期間才能知道):

    NullExcepiton ,  10/0   , format("")

<code>public</code> <code>class</code> <code>InputNullExcepiton </code><code>extends</code> <code>RuntimeException{}   </code><code>//RuntimeException無需強制處理</code>

<code>public</code> <code>class</code> <code>InputNullExcepiton </code><code>extends</code> <code>Exception{}         </code><code>//自定義異常,建議extends Exception</code>

//資料庫Connection是一種寶貴的資源,很容易稱為業務系統的性能瓶頸

    使用原則:

            晚打開,早關閉  -----  使用時間越短越好

            Connection盡量可以重用

   //資料庫Connection的數量不是無限的,它受限于硬體(CPU)

補:

    java.util 類 Date      //除了dao層之外,都盡量使用java.util.Date

    java.sql 類 Date        //隻能在dao層使用

練習(Java項目):

自定義異常

<code>public</code> <code>class</code> <code>InputNullException </code><code>extends</code> <code>Exception {</code>

<code>    </code><code>public</code> <code>InputNullException(String msg){</code>

web層

<code>public</code> <code>class</code> <code>StuUI {</code>

<code>    </code><code>/**</code>

<code>     </code><code>* 删除學生</code>

<code>     </code><code>*/</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>deleteStuTest(){</code>

<code>        </code><code>StuBiz biz = </code><code>new</code> <code>StuBiz();</code>

<code>        </code><code>try</code> <code>{</code>

<code>            </code><code>biz.deleteStudent(</code><code>"s003234"</code><code>);  </code>

<code>            </code><code>System.out.println(</code><code>"删除完畢!"</code><code>);</code>

<code>        </code><code>} </code><code>catch</code> <code>(Exception e) {</code>

<code>            </code><code>e.printStackTrace();</code>

<code>            </code><code>System.out.println(</code><code>"系統異常,請檢查"</code><code>);</code>

<code>        </code><code>}      </code>

<code>     </code><code>* 添加學生</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>addStuTest(){</code>

<code>        </code><code>TStudent ts = </code><code>new</code> <code>TStudent();</code>

<code>        </code> 

<code>        </code><code>ts.setSname(</code><code>"jack"</code><code>);</code>

<code>        </code><code>ts.setSno(</code><code>"s002244"</code><code>);</code>

<code>        </code><code>ts.setCno(</code><code>"c0124"</code><code>);</code>

<code>        </code><code>ts.setSex(</code><code>"f"</code><code>);</code>

<code>        </code><code>ts.setAddress(</code><code>"taiyuan"</code><code>);</code>

<code>        </code><code>ts.setTel(</code><code>"155345263"</code><code>);</code>

<code>        </code><code>String s = </code><code>"2012-06-21"</code><code>;</code>

<code>        </code><code>SimpleDateFormat sdf = </code><code>new</code> <code>SimpleDateFormat(</code><code>"yyyy-MM-dd"</code><code>);</code>

<code>        </code><code>java.util.Date d1 = </code><code>null</code><code>;</code>

<code>            </code><code>d1 = sdf.parse(s);</code>

<code>        </code><code>} </code><code>catch</code> <code>(ParseException e1) {</code>

<code>            </code><code>e1.printStackTrace();</code>

<code>        </code><code>} </code><code>//先把字元串轉為util.Date對象</code>

<code>        </code><code>java.sql.Date d2 = </code><code>new</code> <code>java.sql.Date(d1.getTime()); </code>

<code>        </code><code>ts.setBirthday(d2);</code>

<code>        </code><code>ts.setHeight(</code><code>54</code><code>);</code>

<code>        </code><code>ts.setState(</code><code>1</code><code>);</code>

<code>            </code><code>biz.addStu(ts);</code>

<code>            </code><code>System.out.println(</code><code>"添加學生成功!"</code><code>);</code>

<code>        </code><code>} </code><code>catch</code><code>(InputNullException e){</code>

<code>            </code><code>System.out.println(</code><code>"入參為空!"</code><code>);</code>

<code>        </code><code>}</code><code>catch</code> <code>(Exception e) {</code>

<code>            </code><code>System.out.println(</code><code>"插入失敗!"</code><code>);</code>

<code>        </code><code>}</code>

<code>     </code><code>* 查詢所有學生資訊</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>showStu(){</code>

<code>            </code><code>List&lt;TStudent&gt; stus = biz.findAllStu();</code>

<code>            </code><code>Iterator&lt;TStudent&gt; it = stus.iterator();</code>

<code>            </code><code>while</code><code>(it.hasNext()){</code>

<code>                </code><code>TStudent t = it.next();</code>

<code>                </code><code>System.out.println(t.getSname() + </code><code>"--"</code> <code>+ t.getSno() + </code><code>"--"</code> <code>+ t.getBirthday());</code>

<code>            </code><code>}</code>

<code>            </code><code>System.out.println(</code><code>"查詢失敗!"</code><code>);</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) {</code>

<code>        </code><code>StuUI.showStu();</code>

業務邏輯層:

<code>public</code> <code>class</code> <code>StuBiz {</code>

<code>     </code><code>*    注意: 1. 當學生沒有産生業務資料時,直接删除實體記錄</code>

<code>     </code><code>*        2.  當學生産生了業務資料時,隻能做邏輯删除</code>

<code>     </code><code>* @param sno</code>

<code>     </code><code>* @throws Exception</code>

<code>    </code><code>public</code> <code>void</code> <code>deleteStudent(String sno) </code><code>throws</code> <code>Exception{</code>

<code>        </code><code>if</code><code>(sno != </code><code>null</code><code>){</code>

<code>            </code><code>StuDao dao = </code><code>new</code> <code>StuDao();</code>

<code>            </code><code>try</code> <code>{</code>

<code>                </code><code>dao.deleteStudent(sno);</code>

<code>            </code><code>}</code><code>catch</code><code>(java.sql.SQLIntegrityConstraintViolationException e){</code>

<code>              </code><code>if</code><code>(e.getSQLState().equals(</code><code>"23000"</code><code>)){</code>

<code>                  </code><code>//找到了子記錄</code>

<code>                  </code><code>try</code> <code>{</code>

<code>                      </code><code>dao.updateStuState(</code><code>0</code><code>, sno);</code>

<code>                  </code><code>} </code><code>catch</code> <code>(Exception e2) {</code>

<code>                      </code><code>e2.printStackTrace();</code>

<code>                      </code><code>throw</code> <code>e2;</code>

<code>                  </code><code>}</code><code>finally</code><code>{</code>

<code>                      </code><code>dao.closeConnection();</code>

<code>                  </code><code>}                 </code>

<code>              </code><code>}</code>

<code>            </code><code>} </code><code>catch</code> <code>(Exception e) {            </code>

<code>                </code><code>throw</code> <code>e;</code>

<code>            </code><code>}</code><code>finally</code><code>{</code>

<code>                </code><code>dao.closeConnection();</code>

<code>                        </code> 

<code>        </code><code>}</code><code>else</code><code>{</code>

<code>            </code><code>throw</code> <code>new</code> <code>Exception(</code><code>"入參錯誤,sno=null"</code><code>);</code>

<code>     </code><code>* @param ts</code>

<code>    </code><code>public</code> <code>void</code> <code>addStu(TStudent ts) </code><code>throws</code> <code>Exception{</code>

<code>        </code><code>if</code><code>(ts!=</code><code>null</code><code>){</code>

<code>                </code><code>boolean</code> <code>bet = dao.findClass(ts.getCno());</code>

<code>                </code><code>if</code><code>(!bet){</code>

<code>                    </code><code>throw</code> <code>new</code> <code>Exception(</code><code>"班級不存在"</code><code>);</code>

<code>                </code><code>}</code><code>else</code><code>{</code>

<code>                    </code><code>dao.addStu(ts);</code>

<code>                </code><code>}</code>

<code>            </code><code>} </code><code>catch</code> <code>(Exception e) {</code>

<code>            </code><code>}</code><code>finally</code> <code>{</code>

<code>            </code><code>}      </code>

<code>            </code><code>throw</code> <code>new</code> <code>Exception(</code><code>"入參錯誤!"</code><code>);</code>

<code>     </code><code>* @return</code>

<code>    </code><code>public</code> <code>List&lt;TStudent&gt; findAllStu() </code><code>throws</code> <code>Exception {</code>

<code>     </code><code>//注意:面向接口程式設計不能是實作類傳回</code>

<code>        </code><code>List&lt;TStudent&gt; stus;</code>

<code>        </code><code>StuDao dao = </code><code>new</code> <code>StuDao();</code>

<code>            </code><code>stus = dao.findAllStu();</code>

<code>            </code><code>throw</code> <code>e;</code>

<code>        </code><code>}</code><code>finally</code> <code>{</code>

<code>            </code><code>dao.closeConnection();</code>

<code>        </code><code>return</code> <code>stus;</code>

資料層:

<code>public</code> <code>class</code> <code>StuDao </code><code>extends</code> <code>BaseDao{</code>

<code>    </code><code>public</code> <code>void</code> <code>deleteStudent(String sno) </code><code>throws</code> <code>Exception{       </code>

<code>        </code><code>String sql = </code><code>"delete from tstudent where sno=?"</code><code>;</code>

<code>        </code><code>this</code><code>.openConnection();</code>

<code>        </code><code>PreparedStatement ps = </code><code>this</code><code>.conn.prepareStatement(sql);</code>

<code>        </code><code>ps.setString(</code><code>1</code><code>, sno);</code>

<code>        </code><code>ps.executeUpdate();</code>

<code>        </code><code>ps.close();    </code>

<code>     </code><code>* 修改學生的狀态值</code>

<code>     </code><code>* @param state</code>

<code>    </code><code>public</code> <code>void</code> <code>updateStuState(</code><code>int</code> <code>state,String sno) </code><code>throws</code> <code>Exception{</code>

<code>        </code><code>String sql = </code><code>"update tstudent set state=? where sno=?"</code><code>;</code>

<code>        </code><code>ps.setInt(</code><code>1</code><code>, state);</code>

<code>        </code><code>ps.setString(</code><code>2</code><code>, sno);</code>

<code>        </code><code>ps.close();</code>

<code>    </code><code>public</code> <code>void</code> <code>addStu(TStudent ts) </code><code>throws</code> <code>Exception {</code>

<code>        </code><code>String sql = </code><code>"insert into tstudent values(?,?,?,?,?,?,?,?,?)"</code><code>;</code>

<code>        </code><code>//資料庫打開</code>

<code>        </code><code>ps.setString(</code><code>1</code><code>, ts.getSname());</code>

<code>        </code><code>ps.setString(</code><code>2</code><code>, ts.getSno());</code>

<code>        </code><code>ps.setString(</code><code>3</code><code>, ts.getCno());</code>

<code>        </code><code>ps.setString(</code><code>4</code><code>, ts.getSex());</code>

<code>        </code><code>ps.setString(</code><code>5</code><code>, ts.getAddress());</code>

<code>        </code><code>ps.setString(</code><code>6</code><code>, ts.getTel());</code>

<code>        </code><code>ps.setDate(</code><code>7</code><code>, ts.getBirthday());</code>

<code>        </code><code>ps.setInt(</code><code>8</code><code>, ts.getHeight());</code>

<code>        </code><code>ps.setInt(</code><code>9</code><code>, ts.getState());</code>

<code>                    </code> 

<code>     </code><code>* 添加學生的時候,檢查班級是否存在</code>

<code>     </code><code>* @param cno</code>

<code>    </code><code>public</code> <code>boolean</code> <code>findClass(String cno) </code><code>throws</code> <code>Exception {</code>

<code>        </code><code>boolean</code> <code>bRet = </code><code>false</code><code>;</code>

<code>        </code><code>String sql = </code><code>"select * from tclass where cno=?"</code><code>;</code>

<code>        </code><code>ps.setString(</code><code>1</code><code>, cno);</code>

<code>        </code><code>ResultSet rs = ps.executeQuery();</code>

<code>        </code><code>while</code><code>(rs.next()){</code>

<code>            </code><code>bRet = </code><code>true</code><code>;</code>

<code>        </code><code>rs.close();</code>

<code>        </code><code>return</code> <code>bRet;</code>

<code>        </code><code>List&lt;TStudent&gt; stuList;</code><code>//寫成兩行</code>

<code>        </code><code>String sql = </code><code>"select * from tstudent"</code><code>;</code><code>//寫在openConnection之前</code>

<code>        </code><code>stuList = </code><code>new</code> <code>ArrayList&lt;TStudent&gt;();</code><code>//這樣如果前面有錯就不用産生記憶體配置設定</code>

<code>            </code><code>TStudent ts = </code><code>new</code> <code>TStudent();</code><code>//new TStudent()是建立一個記憶體,這個不會被釋放掉,隻不過每次會建立對象引用</code>

<code>            </code><code>ts.setSname(rs.getString(</code><code>"sname"</code><code>));</code>

<code>            </code><code>ts.setCno(rs.getString(</code><code>"cno"</code><code>));</code>

<code>            </code><code>ts.setSno(rs.getString(</code><code>"sno"</code><code>));</code>

<code>            </code><code>ts.setAddress(rs.getString(</code><code>"address"</code><code>));</code>

<code>            </code><code>ts.setSex(rs.getString(</code><code>"sex"</code><code>));</code>

<code>            </code><code>ts.setTel(rs.getString(</code><code>"tel"</code><code>));</code>

<code>            </code><code>ts.setBirthday(rs.getDate(</code><code>"birthday"</code><code>));</code>

<code>            </code><code>ts.setHeight(rs.getInt(</code><code>"height"</code><code>));</code>

<code>            </code><code>ts.setState(rs.getInt(</code><code>"state"</code><code>));</code>

<code>            </code><code>stuList.add(ts);</code><code>//集合裡面放的是引用,向集合中添加,就是複制對象位址,然後釋放這個對象位址</code>

<code>        </code><code>return</code> <code>stuList;</code>

basedao

<code>public</code> <code>class</code> <code>BaseDao {</code>

<code>    </code><code>protected</code> <code>Connection conn;       </code>

<code>    </code><code>public</code> <code>void</code> <code>openConnection() </code><code>throws</code> <code>Exception{</code>

<code>        </code><code>//通過反射技術,對oracel的驅動對象進行類的加載 (其實是在做類型檢查)</code>

<code>        </code><code>//在類的加載時,會調用OracleDriver中的靜态代碼塊和靜态變量初始化</code>

<code>        </code><code>Class.forName(</code><code>"oracle.jdbc.driver.OracleDriver"</code><code>);  </code>

<code>        </code><code>conn = DriverManager.getConnection(</code><code>"jdbc:oracle:thin:@10.0.19.252:1521:orcl"</code><code>,</code><code>"itxy"</code><code>,</code><code>"itxy"</code><code>);</code>

<code>    </code><code>public</code> <code>void</code> <code>closeConnection() {</code>

<code>        </code><code>if</code><code>(</code><code>this</code><code>.conn != </code><code>null</code><code>){</code>

<code>                </code><code>this</code><code>.conn.close(); </code>

<code>                </code><code>e.printStackTrace();</code>

版權聲明:原創作品,謝絕轉載。否則将追究法律責任

本文轉自 叫我北北 51CTO部落格,原文連結:http://blog.51cto.com/qinbin/1965567