Java資料庫編程

來源:互聯網
上載者:User

標籤:

1. 資料庫編程基本流程

  (1)載入資料庫廠商的驅動程式

  例如:對於Mysql資料庫,Class.forName("com.mysql.jdbc.Driver");

  (2)獲得資料庫連接對象

  Connection connection = DriverManager.getConnection(url,username,password);

  (3)建立資料庫執行語句對象

  Statement  statement = connection.createStatement();

  (4)執行SQL語句,獲得結果集對象

  ResultSet result = statement.executeQuery("SELECT * FROM tb_test");

  (5)關閉資料庫連接

  使用完ResultSet、Statement以及Connection對象後,需要及時調用它們的close方法來釋放資源。關閉Statement對象時,會自動釋放由其獲得的所有ResultSet對象,關閉Connection對象也會自動釋放由其獲得的Statement對象。因此,調用Connection的close方法就可以釋放與其相關的所有資源。

  由於資料庫連接使用完後必須關閉,因此通常將調用close方法放在finally子句中。

 

2. JDBC擷取自增主鍵

  很多時候,我們插入一個記錄的主鍵是自增的列,我們可能緊接著需要獲得這個主鍵,JDBC提供了統一的介面:

  statement.executeUpdate("INSERT....",Statement.RETURN_GENERATED_KEYS);

  ResultSet result = statement.getGeneratedKeys();

  其中,參數Statement.RETURN_GENERATED_KEYS指定返回剛插入的鍵,然後調用getGeneratedKeys方法返回這些鍵。

 

3. 執行事務

  事務表示具有原子性的SQL語句的組合,這些SQL語句要麼全部執行成功,要麼就全部不執行。

  預設情況下,我們建立的Connection對象處於自動認可模式,即執行了一條SQL更新語句,就立即提交更新資料庫。執行事務時,我們需要設定Connection對象不自動認可:connection.setAutoCommit(false);

  然後我們就可以執行多條SQL更新語句,這些對資料庫的更新只有在調用Connection對象的commit方法後才會生效,如果執行這些SQL語句中出現了錯誤,就調用rollback方法復原資料庫。

 

4. 資料庫連接池

  當在多線程環境下進行資料庫編程時,就需要注意同步的問題。

  使用一個全域的Connection對象若不進行同步就會導致並發的各種問題,而對這個全域Connection進行同步,通常效率又是很低的。我們可以使用局部的Connection對象,每次執行資料庫任務時都建立一個新的串連,使用完後立即關閉,這樣會導致頻繁的建立關閉資料庫連接,效率也會比較低。

  更好的方式使用資料庫連接池來管理資料庫串連,資料庫連接池可以有效地利用閑置的資料庫連接。想要串連資料庫時,通過資料庫連接池請求一個Connection對象,這個Connection可能是新建立的,也可能是之前建立尚未關閉的。關閉Connection對象時並不是真的與資料庫中斷連線,而是歸入到資料庫連接池的閑置串連中。

  實現一個資料庫連接池最重要的問題就是解決調用Connection的close方法時,如何不真正關閉資料庫連接。我們可以使用Java動態代理來解決這個問題。

  由於Connection是一個介面,而DriverManager.getConnection方法返回的Connection的具體類型我們又不知道,我們就無法直接通過覆蓋來實現新的close方法。我們當然也可以自己實現Conneciton介面,但這樣我們就需要實現許多介面方法,而實際上我們只需要改變close方法的實現。

  Java反射庫中的Proxy類為我們提供了這樣的能力:可以構造一個實現一些介面的類,並指定一個調用處理器(實現InvocationHandler介面)來攔截對所有介面方法的調用。

  下面給出一個簡易實現的資料庫連接池:

public class DBConnectionPool{    private String jdbcUrl;    private String username;    private String password;    private LinkedList<Connection> pool;  //儲存閑置的Connection對象        public DBConnectionPool(String driver,String jdbcUrl) throws ClassNotFoundException    {        this.jdbcUrl = jdbcUrl;        Class.forName(driver);          pool = new LinkedList<Connection>();    }        public DBConnectionPool(String driver,String jdbcUrl,String username,String password) throws ClassNotFoundException    {       this.jdbcUrl = jdbcUrl;       this.username = username;       this.password = password;       Class.forName(driver);       pool = new LinkedList<Connection>();    }    
//為了可以在多線程環境下使用,對一些方法使用synchronized關鍵字同步 public synchronized Connection getConnection() throws SQLException { Connection conn = null; if(pool.size() > 0) conn = pool.poll(); else { final Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
//建立代理對象,並強制轉換為Connection介面類型,InvocationHandler介面表示調用處理器 conn = (Connection)Proxy.newProxyInstance(null,new Class[]{Connection.class},new InvocationHandler(){ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName() == "close" && method.getParameterTypes().length == 0) { pool.add((Connection)proxy); //執行close方法時,替換原方法的邏輯 return null; } else //執行其他方法時,保持原方法的邏輯 return method.invoke(connection,args); } }); } return conn; } public synchronized Connection getConnection(String username, String password) throws SQLException { Connection conn = null; if(pool.size() > 0) conn = pool.poll(); else { final Connection connection = DriverManager.getConnection(jdbcUrl, username, password); conn = (Connection)Proxy.newProxyInstance(null,new Class[]{Connection.class},new InvocationHandler(){ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName() == "close" && method.getParameterTypes().length == 0) { pool.add((Connection)proxy); return null; } else return method.invoke(connection,args); } }); } return conn; } public synchronized void reduce() throws SQLException { int size = pool.size(); while(pool.size() > (size / 2) ) pool.poll().close(); } public synchronized void close() throws SQLException { while(pool.size() > 0) pool.poll().close(); }}

 

  

Java資料庫編程

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.