我正在开发一个使用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