为连接静态或非静态创建对象的实例变量更好

时间:2015-09-25 10:00:08

标签: java jdbc static connection

我有一个单独的课程,我保持连接。

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;
}

}

在另一个“主要”课程中,我有:

public class TableWithBottomLine extends JPanel implements TableModelListener {

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

在几个地方的同一个“主”课程中,我调用connection = ConnectionManager.getConnection();并执行一些与查询相关的操作。现在我想知道,将这些实例变量设为静态更好吗?为了性能/安全性。如果有人可以分享他们的见解,那将非常高兴。

3 个答案:

答案 0 :(得分:1)

如果Connectionstatic,则只能使用一个实例来访问数据库。

通常,最好的方法是使用ThreadLocal连接,每个线程只有一个Connection。这将允许使用多线程而不会失去性能,但对同一个线程使用相同的Connection,这样您只能在特定步骤结束时处理commit(或rollback)操作。

答案 1 :(得分: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的所有实例共享相同的连接对象 - 这是您想要的吗?

答案 2 :(得分:1)

推荐的方法是使用DataSource(JDBC)或EntityManager(JPA)。 其中一个优点是:您可以使用连接池来获得池化连接。这很好,因为创建连接非常昂贵。

在Java EE环境中,您只需注入DataSource或EntityManager。应用程序服务器将管理连接。

在Java SE环境中,您可以使用例如。 c3p0创建具有池连接支持的DataSource:http://www.mchange.com/projects/c3p0/#using_c3p0

DataSource教程:https://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html

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