5

我想知道使用以下连接变量的安全和更好的方法。

第一:连接作为类的类成员变量

class MyClass
{
    Connection conn;

    public MyClass(Connection conn) {
        this.conn = conn;
    }

    public void myMethod(){
        //Do some DB operations using conn
    }
}

第二:在方法中初始化连接

class MyClass
{       
    public MyClass() {      
    }

    public void myMethod(){
        Connection conn= initializeFunction(); //Initialize Connection
        //Do some DB operations using conn
    }
}

第三:将连接作为参数发送给函数

class MyClass
{       
    public MyClass() {      
    }

    public void myMethod(Connection conn){
        //Do some DB operations using conn
    }
}

注意:问题不是特定于编程语言的,因此我还添加了 Java 以外的标签。

4

8 回答 8

6

这三种方法都提供不同的功能:

  1. 您的类拥有连接对象,只要您的对象保持活动状态,连接对象就会保持活动状态。
  2. 连接对象是方法的本地对象,一旦方法返回就会过期。
  3. 方法的调用者拥有连接对象。

选择取决于:

  • 你想如何处理连接对象的所有权&
  • 您需要记住,数据库连接只需要在需要时打开,而不是一直打开,同时,
  • 您希望连接到数据库的频率。
于 2012-10-04T07:40:12.997 回答
5

对于数据库连接对象,最好的办法是:尽可能晚地打开,尽可能早地关闭

在 C# 中,有一条using语句适用于实现 IDisposable 接口的对象。using语句的工作方式类似于 try/finally 代码块。IMO 处理连接的一般做法应该是这样的:

try
{
connection = new Connection();
connection.Open(); // open the connection
//work with the connection, DB CRUD operations
}
finally
{
if(connection != null)
     connection.Close(); // close the connection in finally block
                         // so that even if the exception occurs, connection gets closed. 
}

对于您的选择,我相信第一个是最差的,它将连接对象与类的对象一起保存。

我认为你应该更关心打开/关闭连接,而不是在多个地方保存连接的对象。

于 2012-10-04T07:38:18.020 回答
4

正确的使用方法Connection是始终声明Connectioninsideusing语句:

using (var connection = InitializeConnection())
{
}

即使抛出异常,它也会自动关闭连接。

幸运的是,ADO.NET 在幕后使用连接池自动为您管理和优化与数据库的连接,因此您无需关心应用程序中打开了多少连接。它们只是逻辑连接

不要只保持连接很长时间,因为它会降低性能并且不使用连接池的并行访问

于 2012-10-04T07:43:10.643 回答
3

根据要求,我会选择选项 1 或 3。

  • 如果有比使用连接定义的方法更多的方法,我会选择选项 1。使用方法 1 很容易使用Dependency InjectionInversion of Control

  • 如果我的班级上的那个方法是使用连接的唯一方法,我会选择选项 3。

方法 2 很难测试,因为您无法为连接定义模拟对象。

此外,我建议不要将类型而是接口传递给MyClass.

于 2012-10-04T07:44:01.483 回答
3

这取决于您是否要提供在方法之外修改 Connection 对象的能力。

就我个人而言,我会选择选项 1 或 2。 Option 1如果 MyClass 是一个具有多个关联方法的数据库容器,即连接到数据库、SharePoint、运行存储过程等 Option 2,如果连接对象仅使用了很短的时间,即打开连接并在其他地方处理数据。Option 3,我不希望将 Connection 对象传递给方法,但这只是个人喜好。

于 2012-10-04T07:45:26.857 回答
3

首选解决方案完全取决于编程环境。对于 Java 或任何其他长时间运行的进程来说是正确的,对于 PHP 和类似的按请求执行来说是错误的。

在 Java 中,您通常有一个要使用的数据库连接池,用于限制与数据库的并发连接数,因为它们大部分时间都是空闲的。平均而言,您不需要与代码中的查询一样多的连接。但另一方面,如果您仅在必须执行第一个查询时才连接到数据库,那将是浪费时间。Java 程序一直在运行,为什么不在 statup 上打开适当数量的 DB 连接呢?然后他们就可以在需要时做好准备。

在 PHP 中,当脚本结束时,所有内容都会被遗忘并在内存中删除。根本没有地方可以存储活动的正在进行的数据库连接。因此,最好的方法是在您确定必须发送查询的那一刻连接到数据库。另一方面,我不同意在 PHP 中“尽早关闭它”,因为它会在脚本结束时关闭,这已经足够快了。过早关闭连接可能意味着您必须重新打开它以进行另一个查询。

I would also object to the idea of singletons for the DB connection in PHP (Java might be a different game). Yes, you normally would have only one database, but what if not? Singletons prevent you from using two databases, don't start with it. mysqli_connect() uses an existing connection if you use the same connection parameters (server, username, password) and acts like a singleton for you, so there is no need to do it again in PHP.

于 2012-10-04T07:51:56.547 回答
2

我会选择第二个选项,稍作修改。我会将对 的调用更改为initializeFunction()Singleton对象,这将产生一个连接。然后,您将在不再需要它时将其关闭。

于 2012-10-04T07:39:13.450 回答
1

这取决于您的连接是否将被许多方法使用。我会建议尽快打开和关闭它,所以 option2 最适合我。只需在需要时使用连接。您可能还对用于汇集连接的c3po库感兴趣。

一般来说,如果我在类中的其他地方使用的变量被删除,我会使用 option1 并使 Connection 成为最终的。由于这是一个数据库连接,我认为规则略有变化。

于 2012-10-04T07:39:39.707 回答