【发布时间】:2009-03-12 12:34:08
【问题描述】:
我即将开始我的课程的开发阶段,目前的设计是拥有一个处理数据库连接的类和许多调用它的类;数据库类应该打开连接并盲目地传递查询,其他类负责这些查询的内容。
我想知道的是,这些参考资料了解数据库类的最佳方式是什么?我的直觉是将 Database 类中的方法设为静态并将它们称为 Database.method() 但有更好的方法吗?
附:引用这个词是正确的吗?如果不是正确的词,下次我有类似的问题时会有所帮助。
【问题讨论】:
我即将开始我的课程的开发阶段,目前的设计是拥有一个处理数据库连接的类和许多调用它的类;数据库类应该打开连接并盲目地传递查询,其他类负责这些查询的内容。
我想知道的是,这些参考资料了解数据库类的最佳方式是什么?我的直觉是将 Database 类中的方法设为静态并将它们称为 Database.method() 但有更好的方法吗?
附:引用这个词是正确的吗?如果不是正确的词,下次我有类似的问题时会有所帮助。
【问题讨论】:
小心点。
单例将成为瓶颈。
java.sql.Connection 不是线程安全的,因此您可能会遇到问题。
我建议您在编写应用时将服务层和持久层完全分开。两者都应该基于接口。服务层是了解工作单元和事务的层,使用模型和持久性对象来实现它们。服务应该负责获取连接,使其可用于持久层,处理事务,并在创建连接的同一方法范围内关闭连接。
范围和清理是关键。如果不这样做,您将耗尽数据库连接。
你没有提到连接池。我会推荐一个。
看看春天。它的 JDBC 模块很好地处理了这一切。如果你不能使用 Spring 来完成你的任务,至少它会是一个很好的模型来设计你的实现。
【讨论】:
传统方法是为每个数据类设置一个 DAO(数据访问对象)。
即如果你有一个数据类“Person”,那么你还有一个类“PersonDAO”,它实现了 findById()、findAll()、save(Person) 等方法。基本上 DAO 类处理所有 DB 交互。
DAO 类的构造函数可以简单地接受一个 Connection 对象,从而将创建连接的问题外部化,或者它可以在某个地方调用一个工厂方法来分配一个 Connection 对象。
在任何一种情况下,您都可能希望拥有这样的工厂方法。
public class Database{
public static Connection getConnection(){
// Create a new connection or use some connection pooling library
}
}
正如有人指出 java.sql.Connection 不是线程安全的,所以你不应该每次都分发同一个连接,除非你确定多个线程不会访问该方法。
当然,如果您需要为每次通话创建新连接,您还需要在完成后关闭连接。简单的方法是向 DAO 添加 close() 方法并让它们处理它。这确实给使用 DAO 的代码带来了负担。
即使您使用连接池,在完成连接后仍然需要关闭连接(返回池)。
有人建议使用 Thread local 来建立每个线程的连接。这在某些情况下有效,但对于每个请求都是一个新线程(从不重用,最好不存储引用)的 Web 应用程序来说没有用。
但是,如果您已对其进行配置,则可以在 web 应用程序中利用此功能,以便在处理每个请求后调用 Database.closeConnection(),然后如果存在 Tread 本地连接,则该连接负责关闭。
【讨论】:
避免任何静态的东西。首选"Parameterisation from Above"。
所以你想要做的是在你的'main'附近创建你的数据库包装对象。然后将其作为构造函数参数传递给需要它的对象。
【讨论】:
如果你按照你的建议去做,那么你将很难对你的类进行单元测试。一种方法可能是将您的数据库信息传递给进行查询的类,例如
Query query = new GetPersonQuery(Database database);
query.run(); // or whatever
如果您使用的是 DAO 模式,这将特别有效,因此:
PersonDao dao = new PersonDao(Database database);
dao.findAll();
然后数据库可以打包您需要的任何内容,例如连接池、缓存等
【讨论】:
如果你想静态存储连接,至少使用线程本地。但正如其他人所说的那样 - 最好将连接或其包装器注入需要使用它的对象中。
【讨论】:
Singleton pattern 将为您提供帮助。请在此处查看more info。
这种模式(正确地)在这里很不受欢迎,因为它本质上是使一堆方法全局化,这在面向对象的世界中是要避免的——但是对于课程作业和你想要实现的目标可能是最简单的。
【讨论】: