2015-09-25 34 views
1

我有一個獨立的類,我保持連接。在幾個地方我打電話connection = ConnectionManager.getConnection();,並做一些查詢相關行動爲靜態或非靜態連接創建對象的實例變量更好嗎

public class TableWithBottomLine extends JPanel implements TableModelListener { 

private Connection connection = null; 
private Statement stmt = null; 
private PreparedStatement prepStmt = null; 
private ResultSet resSet = null; 

在同一個「主」類:

public class ConnectionManager { 
private static String url = "jdbc:mysql://localhost/finance";  
private static String driverName = "com.mysql.jdbc.Driver"; 
private static String username = "root"; 
private static String password = ""; 
private static Connection con; 

public static Connection getConnection() { 
    try { 
     Class.forName(driverName); 
     try { 
      con = DriverManager.getConnection(url, username, password); 
     } catch (SQLException ex) {     
      System.out.println("Failed to create the database connection."); 
     } 
    } catch (ClassNotFoundException ex) {    
     System.out.println("Driver not found."); 
    } 
    return con; 
} 

}

在其他的「主」類我。現在我想知道,將這些實例變量設置爲靜態會更好嗎?爲了性能/安全性。如果有人能分享他們的見解,會很開心。

+3

IMO它總是壞在這個circumnstances使用靜態。改用連接池(如[dbcp](https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi)) – BackSlash

+1

都不是。它應該是一個與線程池關聯的局部變量。 – EJP

+0

@EJP謝謝你的回答。我遵循你的建議。兩個問題。 1.使用局部變量執行作業時,代碼中的這些額外行。我認爲重複的代碼不好?和2.在使用它之前,我必須通過給定一個空值來懶惰地創建本地連接變量嗎? – Paul

回答

1

如果Connectionstatic,則只能使用一個實例來訪問數據庫。

通常最好的方法是使用ThreadLocal連接,每個線程只有一個Connection。這將允許在不丟失性能的情況下使用多線程,但對同一個線程使用相同的Connection,因此只能在特定步驟結束時處理commit(或rollback)操作。

1

你想在你的程序中始終只有一個連接實例嗎?

如果是這樣,您的代碼不會做你想做的事情,因爲每次你從某處調用ConnectionManager.getConnection()時,都會創建一個新連接並將其分配給con靜態字段。

您還會丟失對先前連接對象的引用,這看起來像資源泄漏。

你可能想嘗試這樣的:

public class ConnectionManager { 
    private static final String URL = "jdbc:mysql://localhost/finance"; 
    private static final String USER = "root"; 
    private static final String PASSWORD = ""; 

    private static final Connection CONNECTION = createConnection(); 

    private static Connection createConnection() { 
     try { 
      return DriverManager.getConnection(URL, USER, PASSWORD); 
     } catch (SQLException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public static Connection getConnection(){ 
     return CONNECTION; 
    } 
} 

關於你的問題,在客戶端類的實例變量可以作出終審判決,以表明它們只分配一次。你甚至可以擺脫這些領域,並且總是打電話getConnection(),我認爲性能影響不會有任何意義,並且HotSpot也會將電話內聯。

但如果你不試圖讓一個單身的連接,並使用你的ConnectionManager僅僅作爲一個工廠,然後再考慮擺脫con場的,因爲它沒有任何目的即可。然後也使這些客戶端類字段靜態將使所有的TableWithBottomLine實例共享相同的連接對象 - 這是你想要的嗎?

+1

我不是一個Java架構師 - 只是一個純粹的初學者,試圖解決問題並學習一些東西。這就是爲什麼我不能回答這個問題:我是否需要一個靜態連接?我想我明白_static_關鍵字的含義。我只是想知道,使用它有什麼好處/缺點,什麼是商業實踐。從我通過@BackSlash得到的回覆和其他人看起來像dbcp這樣的連接池是最好的選擇。感謝您的時間。 – Paul

+1

我也不是Java架構師:)但我的建議是儘可能簡單地開始解決方案,不要擔心性能問題,因爲你可能花時間優化錯誤的東西。 – tsayen

1

推薦的方法是使用DataSource(JDBC)或EntityManager(JPA)。 其中一個優點是:您可以使用連接池來獲取池連接。這很好,因爲創建連接非常昂貴。

在Java EE環境中,您可以注入DataSource或EntityManager。應用程序服務器將管理連接。

在Java SE環境中,您可以使用例如。c3p0連接與連接池支持創建數據源:http://www.mchange.com/projects/c3p0/#using_c3p0

數據源教程:https://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html

JPA教程:https://docs.oracle.com/javaee/7/tutorial/partpersist.htm