我将一些c3p0池封装在一个用于执行SQL语句的类中。 它以这种方式初始化:
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应用程序,目前没有使用依赖注入框架。
感谢您的时间!
答案 0 :(得分:2)
我假设您没有使用任何DI框架?如果是这种情况,您有几个选择:
将PooledQueryExecutor
传递给需要它的类的构造函数。从测试和架构的角度来看,这实际上非常好。
让需要JDBC的类实现一些简单的界面,如:
interface PooledQueryExecutorAware {
void setPooledQueryExecutor(PooledQueryExecutor executor);
}
然后你甚至可以遍历类并发现哪些实现了这个,并且注入 PooledQueryExecutor
。你是在这里重新发现DI的一步,但没关系。
类似的方法是创建一个抽象基类,该基类需要PooledQueryExecutorAware
作为依赖项,并且protected final
字段持有它。
让每个类都知道PooledQueryExecutor
- 不推荐,不必要的耦合
Singleton是你能做的最差的,不可测试且难以理解的代码。请不要。
ThreadLocal
?忘掉它。请记住,显性是王道。
另请查看JdbcTemplate。它是Spring的一部分,但是你可以只使用spring-jdbc.jar
而不使用整个框架。我认为它可以轻松取代PooledQueryExecutor
。
答案 1 :(得分:0)
我更喜欢设置(注入)池。这样你可以决定某些实例是否应该获得不同的池,你可以用记录器等包装池,并且很清楚哪些类需要池。
我也认为这使代码更容易测试。
答案 2 :(得分:0)
常见的方法,例如Web服务器是让JNDI启动并运行,然后从JNDI获取数据源。 Simpel JDNI实现适用于独立应用程序。
如果在程序中使用依赖注入,那么这是可以在需要时注入的资源的一个很好的示例。这可能意味着Java EE 6或启用Spring / Guice / CDI的应用程序。
答案 3 :(得分:0)
对象代表网络数据包?他们使用数据库连接是什么?这对我来说不合适。您想更多地谈谈您正在尝试做什么,以及您的架构是什么?
我倾向于使数据包对象成为域的纯模型 - 它们可以保持状态,并且它们应该定义行为,但是它们不应该在数据库中徘徊。数据库访问应该是系统的不同部分,存储层或子系统。它中的关键对象很可能是单例(或者,至少它们将只有一个实例,即使它们不是正式的单例),并且能够自然地包含单个全局连接池。 / p>
然后存在域对象如何与存储子系统交互的问题。实际上,在您询问有关连接池时,您的问题基本相同。一般来说,我希望有一些控制器对象来协调程序的工作;他们可以很好地与不同层次的物体交谈,并将它们彼此介绍。
具体示例可以使这种解释更容易。告诉我们您的数据包!