[英]How do you properly close a JDBC connection for reuse?
第一次建立连接时,我能够从数据库中检索信息,但是每当尝试重新连接到数据库并从不同类的数据库中检索更多信息时,它都将不起作用。 我试图将要从数据库中检索到的信息放入Android Studio中的TextViews中,但它们始终显示为“空”。 我将向您显示第一次连接数据库,连接管理器类以及下次尝试连接数据库的代码。 我认为可能是因为未正确关闭连接,但我确保关闭了resultSet,语句和连接。
这是针对我的高级项目的,该项目即将到期,因此我们将不胜感激。 谢谢!
这是我第一次连接数据库的代码:
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
public final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
@Override
protected Boolean doInBackground(Void... params) {
try {
Connection conn = ConnectionManager.getConnection();
Statement st = null;
if (conn != null)
st = conn.createStatement();
ResultSet resultSet = null;
if (st != null)
resultSet = st.executeQuery("SELECT * FROM userinfo WHERE email='" + mEmail + "'");
int counter = 0;
if (resultSet != null)
while (resultSet.next()) {
counter++;
try {
if (mPassword.equals(resultSet.getString("password"))) {
UserLoginInfo.userEmail = mEmail;
UserLoginInfo.fName = resultSet.getString("firstname");
UserLoginInfo.lName = resultSet.getString("lastname");
st.close();
resultSet.close();
conn.close();
return (true);
} else
return (false);
} catch (SQLException e3) {
e3.printStackTrace();
}
}
if (counter == 0)
return false;
// TODO: register the new account here.
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}
@Override
protected void onPostExecute ( final Boolean success){
mAuthTask = null;
showProgress(false);
if (success) {
finish();
startActivity(new Intent("NavDrawer"));
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
@Override
protected void onCancelled () {
mAuthTask = null;
showProgress(false);
}
}
这是我的连接管理器类:
package com.capstone.hammond.wallstreetfantasyleaguefinal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ConnectionManager {
private static String url = "jdbc:oracle:thin:@141.216.24.31:1521:fsdb";
private static String driverName = "oracle.jdbc.driver.OracleDriver";
private static String username = "xxxx";
private static String password = "xxxx";
private static Connection con;
public static Connection getConnection() {
try {
Class.forName(driverName);
try {
if(con !=null)
return con;
else
return con = DriverManager.getConnection(url, username, password);
} catch (SQLException ex) {
// log an exception. for example:
System.out.println("Failed to create the database connection.");
}
} catch (ClassNotFoundException ex) {
// log an exception. for example:
System.out.println("Driver not found.");
}
return con;
}
}
这是我第二次尝试连接到数据库:
package com.capstone.hammond.wallstreetfantasyleaguefinal;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class WeeklyMatchFragment extends Fragment {
TextView user1;
TextView user2;
TextView bank1;
TextView bank2;
String oppFName;
String oppLName;
float oppBank;
View rootview;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.fragment_weekly_match, container, false);
return rootview;
}
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
new MatchDetails();
user1 = (TextView) view.findViewById(R.id.user1);
user1.setText(UserLoginInfo.fName + " " + UserLoginInfo.lName);
bank1 = (TextView) view.findViewById(R.id.bank1);
bank1.setText("Bank: " + UserLoginInfo.bank);
user2 = (TextView) view.findViewById(R.id.user2);
user2.setText(oppFName + " " + oppLName);
bank2 = (TextView) view.findViewById(R.id.bank2);
bank2.setText("Bank: " + oppBank);
}
public class MatchDetails extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
try {
Connection conn = ConnectionManager.getConnection();
ResultSet rs = null;
Statement st = null;
if (conn != null)
st = conn.createStatement();
if (st != null)
rs = st.executeQuery("SELECT * FROM L1_Standings WHERE EMAIL = '" + UserLoginInfo.userEmail + "'");
if (rs != null)
while (rs.next()) {
try {
UserLoginInfo.bank = rs.getInt("BANK");
UserLoginInfo.currOpp = rs.getInt("CURR_OPP");
} catch (SQLException e3) {
e3.printStackTrace();
}
}
Statement st1 = null;
if (conn != null)
st1 = conn.createStatement();
ResultSet rs1 = null;
if (st != null)
rs1 = st1.executeQuery("SELECT * FROM USERINFO WHERE EMAIL = '" + UserLoginInfo.currOpp + "'");
if (rs1 != null)
while (rs1.next()) {
try {
oppFName = rs1.getString("FIRSTNAME");
oppLName = rs1.getString("LASTNAME");
} catch (SQLException e3) {
e3.printStackTrace();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
}
您应该在finally块中关闭JDBC连接。
如果您正在使用JAVA 7,请使用带有资源语句的try-try-with-Resource ;
关于您的问题:
您也可以选择a)显式关闭连接b)编写并在执行连接的ConnectionManager中调用close()方法
在多个任务中重用相同的连接是一个坏主意。 尽管这听起来不错,但在多线程环境中效率不高。 直接连接必须尽快“关闭”。 您正在寻找的是ConnectionPool
是的,您必须关闭每个数据库资源(以相反的顺序):ResultSet,Statement,Connection
语句,结果集和连接是出站网络和数据库资源的对象包装,因此它们不是无限的(在客户端和服务器端)。 因此,无论是在客户端还是在服务器端,这些资源的开放都具有不同的方面。
在客户端,您将某些(出站)资源(即连接)标记为繁忙,而这些资源却是空闲的(我的意思是,一种用法与另一种用法之间)。 如果您不释放该资源,该资源在服务器端也会被标记为繁忙(这里我指的是该资源的服务器端表示),并且由于服务器通常只有有限数量的“插槽”可用,因此另一个客户端可能会看到拒绝了建立新连接的请求,这是错误的,因为也许您实际上并未使用该连接。
我终于可以工作了。 最大的问题不是我不是第一次关闭连接,而是我没有正确调用我的Asynctask。 它必须是:
new MatchDetails().execute((Void) null);
现在,我唯一的问题是在片段打开两次之前,textViews不会更改。 第一次打开它们时,它们会显示为空,但是当我再次打开它们时,它们将更改为应有的状态。 有人对此有任何想法吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.