[英]how to make a one database connection for many methods in java?
我有一个 DAO 类,它有许多操作数据库的方法。 我为所有这样的方法使用一个连接对象(Database.connect() 返回一个连接对象):
class ExampleDAOImpl implements ExampleDAO{
private Connection con = null;
public void method1 () {
con = Database.connect();
....
con.close();
}
public void method2 () {
con = Database.connect();
....
con.close();
}
public void method1 () {
con = Database.connect();
....
con.close();
}
}
这是为每个方法实例化一个新连接并关闭它的好习惯吗? 我现在有错误说“连接关闭后不允许操作”虽然我在每个方法的开头初始化连接并在最后关闭它。 或者最好使用相同的连接对象并有一个单独的方法在我调用它时关闭它?
ExampleDAOImpl
类的对象不是线程安全的。 因此,如果多个线程同时使用相同的ExampleDAOImpl
对象并调用方法,则可能会发生一个关闭连接然后另一个线程尝试使用它的情况。
可能的解决方案:
ExampleDAOImpl
对象永远不会在多线程上下文中使用。 这仍然容易出错。Connection
对象,使用ConnectionPool
来获得在每个方法的开始的连接,并释放它你从它完成之后。创建两个函数一个用于
connection()
另一个为
disconnection()
在每个方法中调用这些方法
function method()
{
//call
connection();
//code;
//call
disconnection();
}
在每种方法中打开连接时建立全局连接有什么意义。 当您从方法 1 调用方法 2 时,这可能会发生,它会关闭方法 1 使用的连接
通常,好的做法是在应用程序生命周期中创建一次连接并在应用程序关闭/退出时关闭连接,因为打开和关闭连接会产生成本。
你的代码不是线程安全的,因为jdbc连接不能同时使用! 请将 Connection con 改为 ThreadLocal,并添加连接和断开两种方法。
代码将如下所示:
public class ConnectionHelper
{
private static ThreadLocal<Connection> con = new ThreadLocal<Connection>();
protected Connection getConnection()
{
if(con.get() ==null)
{
con.set(Database.connect());
}
return con.get();
}
protected Connection closeConnection()
{
if(con.get() !=null)
{
con.get().close;
}
}
}
在您的 DAO 中: public void method1 () { try { Connection con = ConnectionHelper.getConnection(); } 最后{ ConnectionHelper.closeConnection(); } }
如果您正在使用像BoneCP这样的连接池实现,那么为每个方法打开新连接是完全没问题的,只需确保该方法不引用实例变量,而是一个局部变量。
另一方面,如果您没有可用的连接池并且只使用一个连接,则必须找到一个合适的位置来关闭该连接,因为在没有连接池的情况下获取新连接非常昂贵。
如果你想要干你的代码,那么使用抽象类和 lambdas
class ExampleDAOImpl implements ExampleDAO{
// With lambdas
public void method1 () {
withConnection( (Connection con) -> {
// do whatever you want with the connection
// no need to open or close it
})
}
// Old style abstract class
public void method2 () {
withConnection(new TaskExecutor(){
void doStuff(Connection con){
// do whatever you want with the connection
// no need to open or close it
}
})
}
// This is the magic you have to add.
private void withConnection(TaskExecutor executer){
// Instantiate it to avoid race conditions
// good thing this is the only place
// you have to worry about opening and closing it
Connection con = Database.connect();
executer.doStuff(con);
con.close();
}
private abstract class TaskExecutor{
abstract void doStuff(Connection con);
}
}
我通过为所有方法创建一个连接解决了我自己的问题:
public void generateTestData() throws SQLException, ClassNotFoundException, IOException {
ConnectionToDatabase connectionToDatabase = new ConnectionToDatabase();
try (Connection connection = connectionToDatabase.connectToDatabase()) {
{
generateGroups(connection);
generateCourses(connection);
assignCoursesToStudents(connection);
}
}
}
也许对 smb 会有用 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.