2011-11-21 70 views
2

我有一些c3p0池封装在一个用来执行SQL语句的类中。 它的初始化是这样的:在很多类之间共享一个JDBC连接池

public PooledQueryExecutor(String url, Properties connectionProperties) throws DALException { 
     try { 
      dataSource = new ComboPooledDataSource(); 
      dataSource.setDriverClass(DRIVER); 
      dataSource.setJdbcUrl(url); 
      dataSource.setProperties(connectionProperties); 
     } catch (PropertyVetoException ve) { 
      throw new DALException(ve); 
     } 
    } 

然后 - 同一个类里面 - 我用一些方法来执行基本任务:

public CachedRowSet executeSelect(String sql) throws DALException { 
     // Get a connection, execute the SQL, return the rows that match, return resources to the pool 
    } 

的“问题”是:
我有很多的不同代表我收到的网络数据包的类。大多数类需要使用此PooledQueryExecutor来执行数据库操作,但有些不需要。我是否将此PooledQueryExecutor传递给需要它的类的构造函数(80%的数据包),还是将PooledQueryExecutor设置为单例?或者也许是“别的东西”?我也使用ThreadLocal来避免污染我的构造函数,但我认为这不是一个好主意,是吗?

编辑:它不是一个web应用程序,并且当前没有依赖注入框架使用。

谢谢你的时间!

回答

2

我假设你没有使用任何DI框架?如果是这种情况,你有几个选择:

  • 通行证PooledQueryExecutor到需要它的类的构造函数。从测试和架构的角度来看,这实际上非常好。

  • 让需要JDBC类实现一些简单的接口,如:


interface PooledQueryExecutorAware { 

    void setPooledQueryExecutor(PooledQueryExecutor executor); 

} 

那么你甚至可以遍历类,并发现它们实现这一点,注入需要PooledQueryExecutor地方。你是在这里重新发现DI的一个步骤,但没关系。

  • 类似的方法是创建一个抽象基类,需要PooledQueryExecutorAware作为一个依赖,并有protected final场拿着它。

  • 类意识到PooledQueryExecutor - 不推荐的,不必要的耦合

  • 辛格尔顿是最差你可以做什么,不可测的,很难理解的代码。请不要。

  • ThreadLocal?忘掉它。请记住,明确是王道。

也看看JdbcTemplate。它是Spring的一部分,但你只能包括spring-jdbc.jar和其他几个,而不使用整个框架。我认为它可以轻松取代你的PooledQueryExecutor

+0

此刻没有DI框架。实际上我使用反射来创建数据包实例(它们有成千上万个,它们都对相同的构造函数==>“IncomingPacket incomingPacketInstance = incomingPacketConstructor.newInstance(pooledQueryExecutor);”),因此标记使用数据库的数据包的接口是不是一个真正的选择(保持清洁的“反射代码”)。如果我把一些“私人静态PooledQueryExecutor数据库;”在基类内(IncomingPacket)。我只需要设置一次,我就可以为JUnit设置一个模拟对象。 – AndrewBourgeois

+0

你提供了一些非常有趣的细节。我认为“界面”方法现在更好。只需遍历一个'incomingPacketInstance'集合并使用'instanceof'即可。将来,如果你需要更多的依赖关系,你可以添加更多'* Aware'接口。相信我,'static'字段(不能是'final')将来会很痛苦。 –

+0

我将使用接口方法,一旦有多个对象可能(!)在数据包中需要,它确实会更好。谢谢 ! – AndrewBourgeois

0

我更喜欢设置(注入)池。这样,你可以决定是否有一些实例应该获得不同的池,你可以用记录器等来包装这个池,并且清楚哪些类需要该池。

我也认为这使得代码更容易测试。

0

例如, Web服务器,它将JNDI启动并运行,然后从JNDI获取数据源。 Simpel JDNI实现存在于独立应用程序中。

如果您在程序中使用依赖注入,那么这是一个很好的资源示例,可以在需要时注入。这意味着Java EE 6或Spring/Guice/CDI启用的应用程序。

0

对象代表网络数据包吗?他们使用数据库连接的是什么?这不适合我。你想谈谈你想做什么,你的架构是什么?

我会倾向于使数据包对象成为一个纯粹的域模型 - 它们可以保持状态,并且应该定义行为,但是它们不应该在数据库中啃食。数据库访问应该是系统的不同部分,即存储层或子系统。关键对象很可能是单身人士(至少,即使他们不是正式的单身人士,他们也只有一个实例),并且能够很自然地包含一个全局连接池。

那么存在域对象如何与存储子系统交互的问题。事实上,当你问到连接池时,你的问题基本上是一样的。总的来说,我希望有一些控制器对象来协调程序的工作,他们很适合与不同层次的对象交谈,并将它们介绍给对方。

具体的例子会使这个解释更容易。告诉我们您的数据包!