日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文介紹了如何將JDBC Swing Worker與連接池一起使用(理想情況下,同時將SQL和應用程序邏輯分開)?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我有一個帶有Swing圖形用戶界面的Java應用程序,它使用Swing工作器從數據庫(例如,SQLite或MySQL)中提取數據來填充JTable。Swing工作器使用JDBC,一次將多個行塊放入表中。

為此,我使code found here適應了我的目的。該代碼包含一個JDBCModel類,它擴展了AbstractTableModel來存儲JTable的數據。該代碼還包含一個JDBCWorker類,它擴展SwingWorker以訪問數據庫并將行添加到表模型。

JDBCModel的構造函數首先建立連接,執行查詢,然后創建ResultSet

try {
    Statement s = conn.createStatement();
    rs = s.executeQuery(query);
    meta = rs.getMetaData();
    JDBCWorker worker = new JDBCWorker();
    jpb.setIndeterminate(true);
    worker.execute();
} catch (SQLException e) {
    e.printStackTrace(System.err);
}

然后,JDBCWorker只需迭代結果集并為表創建行。JDBCWorker被定義為JDBCModel中的私有類。這是JDBCWorker迭代結果集的方式:

protected List<Row> doInBackground() {
    try {
        while (rs.next()) {
            Row r = new Row();
            // omitting some additional computations for brevity...
            publish(r);
        }
    } catch (SQLException e) {
        e.printStackTrace(System.err);
    }
    return data;
}

在我自己的代碼中,我使用連接池,而不是保持相同的連接活動。我對代碼進行了如下修改,以便能夠從我在單獨的Sql類中定義的數據源請求新連接。我還將私有JDBCWorker類移出了JDBCModel類。每次需要重新填充表時,都會創建一個新的Worker。這是輔助進程現在使用連接池的樣子;它使用try-with-Resources在使用后自動關閉連接、語句和結果集:

protected List<Row> doInBackground() {
    try (Connection conn = sql.getDataSource().getConnection();
            PreparedStatement statement = conn.prepareStatement(query)) {
        ResultSet rs = statement.executeQuery();
        while (rs.next()) {
            Row r = new Row();
            // omitting some additional computations for brevity...
            publish(r);
        }
    } catch (SQLException e) {
        e.printStackTrace(System.err);
    }
    return null;
}

它似乎工作得很好,但我現在關心的是如何正確地分隔我的代碼。我有以下三個相互關聯的問題:

    這是否相當有效,或者是否強烈建議只為工作人員在后臺保持連接活動數小時,就像原始代碼中所做的那樣?
    理想情況下,我希望將所有與SQL和JDBC相關的代碼移到我的Sql類中,以便編寫更清晰的分離代碼。但是看起來Worker的publish方法必須嵌套在結果集的try-with-resource塊中,因為如果該集不在塊中,它就已經關閉了。如何將這兩個任務分離到單獨的類/方法中,而不會使連接永遠處于活動狀態、不會丟失連接跟蹤、不會混淆SQL和圖形用戶界面/表模型代碼?
    是否有辦法在返回的ResultSet對象被銷毀或已到達while循環結束時自動關閉我在Sql類中創建的連接?

推薦答案

在看到trashgod的comment后,我提出了一個解決方案,盡可能地將這兩個問題分開,并在隨后關閉連接。盡管知道它并不完美,但我仍將其作為答案發布,希望有人能提出更好的方案。

在我的Sql類中,我創建了一個方法,該方法執行查詢并將結果集與語句和連接一起保存,然后返回所有內容:

public SqlStuff getSqlStuff() {
    String query = "SELECT * FROM MyTable;";
    ResultSet rs = null;
    Connection conn = null;
    PreparedStatement statement = null;
    try {
        conn = getDataSource().getConnection();
        statement = conn.prepareStatement(query);
        rs = statement.executeQuery();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        // nothing to close here because the result set is still needed
    }
    SqlStuff s = new SqlStuff(rs, tableStatement, conn);
    return s;
}

一旦提取了數據,Swing Worker就需要關閉連接、語句和結果集,因此還不能關閉它們,所有這些都需要存儲在SqlStuff對象中并為此返回。該容器對象定義如下:

public class SqlStuff implements AutoCloseable {
    ResultSet rs;
    PreparedStatement ps;
    Connection c;
    
    public SqlStuff(ResultSet rs, PreparedStatement ps, Connection c) {
        this.rs = rs;
        this.ps = ps;
        this.c = c;
    }
    
    public void close() {
        rs.close();
        ps.close();
        c.close();
    }
    
    public ResultSet getResultSet() {
        return rs;
    }
}

SqlStuff類實現AutoCloseableclose方法。因此,Swing輔助進程可以在try-with-resource塊中使用它,并且在完成后它將自動關閉連接、語句和結果集。Swing工作器按如下方式處理結果:

protected List<TableDocument> doInBackground() {
    
    try (SqlStuff s = sql.getSqlStuff();
            ResultSet rs = s.getResultSet()) {
        while (rs.next()) {
            Row r = new Row(rs.getString(1));
            // omitting additional getString and getInt calls for brevity
            publish(r);
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

由于AutoCloseable接口,doInBackground函數在處理結果集后關閉連接、語句和結果集。與我之前的版本相比,性能似乎沒有明顯的差異,而且分離到Sql類和圖形用戶界面/模型關注點更嚴格,這使得每個主題的專家都更易于維護。

但是,這仍然有一些缺點:代碼要長得多。如果其他人開始使用getResultSet方法,他們可能沒有意識到連接仍然需要關閉,可能無法使用帶資源的try或手動調用close。而且仍然沒有完美的關注點分離,因為Swing工作者仍然必須關閉連接并處理結果集(即JDBC代碼)。但我看不出如何才能實現更好的分離(歡迎發表評論)。至少在這段代碼中,我將所有的SQL和一些JDBC內容放在Sql類中,即使有一些開銷。

我猜作為替代方案,我可以將整個doInBackground函數移到單獨的Sql類中,并在Swing工作器中引用它來完成工作。但我不知道如何告訴函數,然后從哪里獲取publish方法。

這篇關于如何將JDBC Swing Worker與連接池一起使用(理想情況下,同時將SQL和應用程序邏輯分開)?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標簽:分開 如何將 應用程序 情況下 時將 理想 邏輯
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定