我正在開發一個使用NetBeans的基於Java的應用程序。我的應用程序打開窗口,要求用戶輸入他們的憑據,並根據輸入的數據,在應用程序和我的MySQL客戶端(我正在使用JDBC)之間建立連接。我的連接對象可以在我的所有表單上使用嗎?
我的問題:我希望連接對象(在檢查用戶憑據後聲明並初始化)可用於我的所有表單。以前,我通過將連接對象從一個窗體傳遞到另一個窗體來完成此操作。但我不想那麼做!我希望一旦這個連接對象被聲明,它就可以被應用程序中的所有表單所使用。
我正在開發一個使用NetBeans的基於Java的應用程序。我的應用程序打開窗口,要求用戶輸入他們的憑據,並根據輸入的數據,在應用程序和我的MySQL客戶端(我正在使用JDBC)之間建立連接。我的連接對象可以在我的所有表單上使用嗎?
我的問題:我希望連接對象(在檢查用戶憑據後聲明並初始化)可用於我的所有表單。以前,我通過將連接對象從一個窗體傳遞到另一個窗體來完成此操作。但我不想那麼做!我希望一旦這個連接對象被聲明,它就可以被應用程序中的所有表單所使用。
我想要的連接對象(...)是可供使用在我所有的形式
你不應該有,而你的應用程序的生命打開的連接。相反,使用一個1或2個連接的數據庫連接池,該連接池將可用於所有應用程序,並在應用程序完成時添加關閉掛鉤以關閉此數據源。連接池將注意保持連接處於活動狀態併爲其使用較低的資源。
例如:您的用戶打開應用程序並輸入其憑據,然後離開房間,因爲他/她必須做一些文書工作並花30分鐘,然後返回到電腦並嘗試使用選項。如果使用static Connection con
對象,則手動打開了與數據庫的物理連接,並且您負責控制所有這30分鐘的連接,如果在此期間沒有執行任何操作,則可能物理連接已關閉由數據庫引擎。如果使用連接池,這將負責打開/關閉物理連接並將它們保持在睡眠狀態,以便連接不會丟失。
請注意,您的Connection
對象和相關資源(PreparedStatement
,ResultSet
等)。應該在儘可能窄的範圍內。
下面是使用BoneCP作爲數據庫連接池的最小示例。
public class ConnectionProvider {
private static DataSource dataSource;
private static boolean initialized = false;
public static void init(Map<String, String> conf) {
if (!initialized) {
//synchronization to avoid multiple threads accesing to this part of the method
//at the "same time"
synchronized(DataSourceProvider.class) {
//double validation in case of multi threaded applications
if (!initialized) {
//you may add more validations here
//in case you want to use another datasource provider
//like C3PO, just change this part of the code
BoneCPDataSource bds = new BoneCPDataSource();
bds.setDriverClass(conf.get("driver"));
bds.setJdbcUrl(conf.get("url"));
bds.setUsername(conf.get("user"));
bds.setPassword(conf.get("password"));
//this should be obtained as configuration parameter
bds.setMaxConnectionsPerPartition(2);
//you can add more BoneCP specific database configurations
dataSource = bds;
initialized = true;
}
}
}
}
public static Connection getConnection() {
if (dataSource == null) {
//this should be a custom exception in your app
throw new RuntimeException("Data Source was not initialized.");
}
return dataSource.getConnection();
}
}
而且客戶端(一旦你叫init
方法和提供的數據庫配置)。爲了簡潔起見,我避免了異常處理:
public class SomeDao {
private Connection con;
//using Dependency Injection by composition for DAO classes with connection
public SomeDao(Connection con) {
this.con = con;
}
public SomeEntity getSomeEntity(int id) {
String sql = "SELECT id, col1, col2 FROM someEntity WHERE id = ?";
//PreparedStatement and ResultSet go on the narrowest possible scope
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
SomeEntity someEntity = new SomeEntity();
if (rs.hasNext()) {
someEntity.setId(rs.getInt("id");
//similar for other columns...
}
//don't forget to close the resources after its usage
return someEntity;
}
}
public class SomeService {
public SomeEntity getSomeEntity(int id) {
//retrieving the connection at this level
//a service may access to several daos
Connection con = ConnectionProvider.getConnection();
//performing the operations against DAO layer
SomeDao someDao = new SomeDao(con);
SomeEntity someEntity = someDao.getSomeEntity(id);
//closing the connection. This is A MUST
//here the connection pool won't close the physical connection
//instead put it to sleep
con.close();
//return the proper data at a single point of the method
return someEntity;
}
}
不要在您的應用程序中使用相同的連接!但是你想要實現的可以使用靜態變量來完成。例如,下面的代碼添加到您的任意課程,或者爲它創建一個新的類:
private static Connection con = null;
public static Connection getConnection (String url)
{
if (con == null)
con = DriverManager.getConnection(url);
return con;
}
然後,調用MyClass.getConnection("jdbc:mysql://localhost:3306/")
或任何連接字符串,它會返回一個Connection
,你可以使用所有課程。
將連接打開並傳遞出去通常是一種很差的做法。如果連接是一個繁瑣的過程,那麼將該過程放在一個方法中,並在需要連接時調用它,並在完成後關閉連接。 – 2014-10-16 23:58:23