如何在java中为多个方法建立一个数据库连接?
我有一个DAO类,它有许多方法操作数据库。我对所有类似的方法使用一个连接对象(Database.connect()返回一个连接对象):如何在java中为多个方法建立一个数据库连接?,java,database,mysql-connector,Java,Database,Mysql Connector,我有一个DAO类,它有许多方法操作数据库。我对所有类似的方法使用一个连接对象(Database.connect()返回一个连接对象): 为每个方法实例化一个新连接并关闭它,这是一个好的做法吗?虽然我在每个方法的开头初始化连接,并在最后关闭连接,但是我现在有错误说“连接关闭后不允许操作”。或者最好使用同一个连接对象,并有一个单独的方法在我调用它时关闭它?为一个对象创建两个函数 connection() 另一个 disconnection() 在每个方法中调用这些方法 functio
为每个方法实例化一个新连接并关闭它,这是一个好的做法吗?虽然我在每个方法的开头初始化连接,并在最后关闭连接,但是我现在有错误说“连接关闭后不允许操作”。或者最好使用同一个连接对象,并有一个单独的方法在我调用它时关闭它?为一个对象创建两个函数
connection()
另一个
disconnection()
在每个方法中调用这些方法
function method()
{
//call
connection();
//code;
//call
disconnection();
}
在每个方法中打开连接时建立全局连接的意义是什么。 当您从method1调用method2时,可能会发生这种情况,因为它会关闭method1使用的连接
一般来说,良好的做法是在应用程序生命周期中创建一次连接,并在应用程序关闭/退出时关闭连接,因为打开和关闭连接会产生成本。您的代码不是线程安全的,因为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;
}
}
}
公共类ConnectionHelper
{
private static ThreadLocal con=new ThreadLocal();
受保护的连接getConnection()
{
if(con.get()==null)
{
con.set(Database.connect());
}
return con.get();
}
受保护的连接closeConnection()
{
if(con.get()!=null)
{
con.get().close;
}
}
}
在你的道中:
公共无效方法1(){
尝试
{
Connection con=ConnectionHelper.getConnection();
}
最后
{
ConnectionHelper.closeConnection();
}
}类
ExampleDAOImpl
的对象不是线程安全的。因此,如果多个线程同时使用相同的ExampleDAOImpl
对象和调用方法,则可能会出现一个线程关闭连接,而另一个线程尝试使用该连接的情况
可能的解决办法:
- 确保在多线程上下文中从不使用
对象。这仍然容易出错ExampleDAOImpl
- 更好的建议:不要使用单个
对象,而是使用连接
在每个方法的开头获取连接,并在完成后释放它连接池
另一方面,如果您没有可用的连接池并且只使用一个连接,则必须找到一个合适的位置来关闭该连接,因为获得没有连接池的新连接非常昂贵。如果您想干燥代码, 然后使用抽象类和lambda
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来说,这可能很有用:)如果这些方法相互调用,内部调用将过早地关闭连接,从而导致您看到的错误。您必须提供有关异常的更多详细信息!例如StackTrace或行号会很有帮助!可能是重复的,或者最好使用相同的连接对象-尝试一下。如果您在程序的整个生命周期中使用数据库,请在程序启动时打开连接,并在退出时关闭。那么您如何确定何时关闭连接?或者,你能举一个这样一个安全出口的例子吗?这提供了同步吗?你不需要对ThreadLocal进行同步,它是线程作用域中的一个变量。
public void generateTestData() throws SQLException, ClassNotFoundException, IOException {
ConnectionToDatabase connectionToDatabase = new ConnectionToDatabase();
try (Connection connection = connectionToDatabase.connectToDatabase()) {
{
generateGroups(connection);
generateCourses(connection);
assignCoursesToStudents(connection);
}
}
}