在 Dao 类中使用静态方法还是非静态方法?

Posted

技术标签:

【中文标题】在 Dao 类中使用静态方法还是非静态方法?【英文标题】:Using Static methods or none static methods in Dao Class? 【发布时间】:2011-02-01 04:50:08 【问题描述】:

您好,我为一些 DB 操作生成了 Dao 类

这样将 Dao 类的方法设置为静态还是非静态比较好?

使用下面的示例 dao 类,如果有多个客户端同时使用 AddSampleItem 方法?这可能会导致什么结果?

public class SampleDao

  static DataAcessor dataAcessor 

  public static void AddSampleItem(object[] params)
  
      dataAcessor =new DataAcessor();
       //generate query here
       string query="..."
      dataAcessor.ExecuteQery(query);
      dataAcessor.Close(); 
   

  public static void UpdateSampleItem(object[] params)
  
      dataAcessor =new DataAcessor();
       //generate query here
       string query="..."
      dataAcessor.ExecuteQery(query);
      dataAcessor.Close(); 
   

【问题讨论】:

【参考方案1】:

这会导致大混乱。如果您从不同的线程同时添加 2 个项目,您肯定会得到非常奇怪的结果,甚至如果一个线程在另一个线程完成之前关闭 DataAcessor 甚至会出错。

我会使用本地 DataAcessor 或创建一个新的并在所有方法中使用它,具体取决于您希望如何管理 DataAcessor 的生命周期。

public class SampleDao

  public void AddSampleItem(object[] params)
  
      DataAcessor dataAcessor =new DataAcessor();
      // ...
  

  public void UpdateSampleItem(object[] params)
  
      DataAcessor dataAcessor =new DataAcessor();
      // ...
  

【讨论】:

【参考方案2】:

我总是喜欢非静态类。依赖项不能注入静态类,单元测试更难。此外,它的客户在进行单元测试时不能用测试替身替换它。

http://googletesting.blogspot.com/2008/12/static-methods-are-death-to-testability.html

【讨论】:

【参考方案3】:

这段代码不像你写的那样是线程安全的。

如果您有这样的 dataAccessor 字段和静态方法,您将遇到多个客户端同时访问此代码的并发问题。您可能会发生非常奇怪的异常,甚至可能一个客户端可以看到另一个客户端的数据。

摆脱这些方法和该字段的静态,并为每个客户端实例化一个新的 SampleDao 实例。

【讨论】:

【参考方案4】:

在每个方法中将新的 DataAccessor 对象分配给静态 DataAccessor 引用会导致并发问题。您仍然可以在 SampleDao 类中使用静态方法,但请确保删除对 DataAccessor 的静态引用。要使用 DataAccessor,请创建一个本地实例。这样可以避免并发问题。这里的缺点是每次调用静态方法时,都会创建一个 DataAccessor 的实例。

在大多数情况下,Daos 是无状态的。在这些情况下,我认为在 Daos 中使用非静态方法毫无意义,因为我们需要创建该 dao 的实例来访问其方法。

【讨论】:

【参考方案5】:

布鲁诺是正确的。但是,您也可以添加一个单例并使用“锁定”来单线程处理应用程序的该部分。但是请记住,请求会排队,如果您的查询需要时间,您的应用程序的性能将会下降。这在 Web 应用程序中尤其明显。对于移动或桌面应用,“锁定”绝对是合适的。

【讨论】:

以上是关于在 Dao 类中使用静态方法还是非静态方法?的主要内容,如果未能解决你的问题,请参考以下文章

同名的静态和实例方法?

java中在一个类中定义的一个静态方法,怎么引用时可以直接用,不用对象.方法,也不用类.方法?

PHP 类中静态方法调用非静态方法

java中静态属性和静态方法的问题

Java中的静态和枚举

静态工具类中使用注解注入service(静态方法调用有注解的非静态方法)