除了特定问题/问题,这是坏练习宣布昂贵的和外部的资源,如Connection
,Statement
和ResultSet
作为一个实例变量,更不用说作为static
变量。这些资源没有无穷无尽的生命周期,当DB决定超时连接时,应用程序可能会中断,因为它在使用后没有被释放回数据库。
我无法想象它在C#中的做法是不同的(它也是应用程序中的一个bug),但是正常的JDBC成语是您在尽可能短的范围内获取并关闭它,同样的方法块。例如。
public Entity find(Long id) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
Entity entity = null;
try {
connection = database.getConnection();
statement = connection.prepareStatement(SQL_FIND);
statement.setLong(1, id);
resultSet = statement.executeQuery();
if (resultSet.next()) {
entity = new Entity();
entity.setProperty(resultSet.getObject("columnname"));
// etc..
}
} finally {
// Always free resources in reversed order.
if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
return entity;
}
的database.getConnection()
可以但是在技术上完全可以做静态这样的:
public final class Database {
static {
try {
Class.forName("com.example.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
private Database() {
// No need to instantiate this class.
}
public static Connection getConnection() {
DriverManager.getConnection("jdbc:example://localhost/dbname", "user", "pass");
}
}
,这样你可以使用它作为
connection = Database.getConnection();
(你还真需要关闭的finally
block after use!)
但是,这使得t他的连线源也真的是static。您不能再利用多态性和/或继承来切换连接源(如连接池)(以获得更好的性能)。为了获得更多想法/见解,您可能会发现this article有用
为什么我需要'final'修饰符? – Pentium10
@ Pentium10:防止类被扩展;如果它可以被扩展,那么它可以被实例化。 –