Java 中的静态连接方法
Static Connection method in Java
我对使用静态连接连接数据库感到困惑。根据我的阅读,不应使用静态连接。这是我的方法:
private static Connection conn()
{
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = (Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
return connection;
}
然后获取结果的新方法:
public void getResult(ArrayList test)
{
try
{
Connection conn = conn();
String sql = "select id from test";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next())
{
test.add(rs.getInt("id"));
}
conn.close();
} catch (SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
}
现在,我不知道这是否安全。每次调用方法时都会重新启动连接(?),我正在关闭它。当然连接池对性能有好处,但是这个线程安全吗?
如果您想使用单个连接,您可以在创建新连接之前声明 Connection object as private instance object
并始终 check if it is null
。
private Connection connection = null;
private static Connection conn()
{
if ( connection == null) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = (Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
}
return connection;
}
public void getResult(ArrayList test)
{
try
{
Connection conn = conn();
String sql = "select id from test";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next())
{
test.add(rs.getInt("id"));
}
} catch (SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
finally{
try {
conn.close();
conn = null;
}
catch(Exception e)
{
//Unable to close connection
}
}
}
从技术上讲它是线程安全的,但如果抛出异常则容易发生连接泄漏。 conn.close()
在这种情况下不会被调用。 conn.close()
应该在 finally 块中,或者修改为使用 try-with-resources 的代码,这将隐式调用它。
try-with-resources (Java 7+) 允许在 try 语句中声明实现 Autocloseable
接口的变量。然后在 try
块的末尾优雅地关闭这些变量。
try( Connection conn = conn(); )
{
//.... other statements
} catch(SQLException e) {
//.... exception code
}
我对使用静态连接连接数据库感到困惑。根据我的阅读,不应使用静态连接。这是我的方法:
private static Connection conn()
{
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = (Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
return connection;
}
然后获取结果的新方法:
public void getResult(ArrayList test)
{
try
{
Connection conn = conn();
String sql = "select id from test";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next())
{
test.add(rs.getInt("id"));
}
conn.close();
} catch (SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
}
现在,我不知道这是否安全。每次调用方法时都会重新启动连接(?),我正在关闭它。当然连接池对性能有好处,但是这个线程安全吗?
如果您想使用单个连接,您可以在创建新连接之前声明 Connection object as private instance object
并始终 check if it is null
。
private Connection connection = null;
private static Connection conn()
{
if ( connection == null) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = (Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
}
return connection;
}
public void getResult(ArrayList test)
{
try
{
Connection conn = conn();
String sql = "select id from test";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next())
{
test.add(rs.getInt("id"));
}
} catch (SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
finally{
try {
conn.close();
conn = null;
}
catch(Exception e)
{
//Unable to close connection
}
}
}
从技术上讲它是线程安全的,但如果抛出异常则容易发生连接泄漏。 conn.close()
在这种情况下不会被调用。 conn.close()
应该在 finally 块中,或者修改为使用 try-with-resources 的代码,这将隐式调用它。
try-with-resources (Java 7+) 允许在 try 语句中声明实现 Autocloseable
接口的变量。然后在 try
块的末尾优雅地关闭这些变量。
try( Connection conn = conn(); )
{
//.... other statements
} catch(SQLException e) {
//.... exception code
}