如何正确关闭JDBC连接以便重用?

时间:2015-04-22 03:33:47

标签: java android database jdbc

我第一次建立连接时能够从数据库中检索信息,但每当我尝试重新连接到数据库并从不同类中的数据库中检索更多信息时,它都无法正常工作。我试图将我从数据库中检索的信息放入Android Studio中的TextViews,但它们一直显示为“null”。我将向您展示我第一次连接到数据库时的代码,我的连接管理器类,以及下次尝试连接数据库时的代码。我认为这可能是因为连接未正确关闭但我确保关闭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;
    }
}

}

3 个答案:

答案 0 :(得分:0)

您应该在finally块中关闭JDBC连接。

如果您使用的是JAVA 7,请使用try with resource statement - try-with-Resource;

答案 1 :(得分:0)

关于您的问题:

  • 您应该a)明确关闭连接b)在ConnectionManager中编写并调用close()方法

  • 在多个任务中重复使用相同的连接是个坏主意。虽然这听起来不错,但在多线程环境中效率不高。必须尽快“关闭”直接连接。您正在寻找的是ConnectionPool

  • 是的,您必须关闭每个数据库资源(按相反顺序):ResultSet,Statement,Connection

语句,结果集和连接是出站网络和数据库资源的对象包装器,因此它们不是无限的(在客户端和服务器端)。因此,在客户端和服务器端,保持这些资源的开放具有不同的方面。

在客户端,您将某些(出站)资源(即连接)标记为忙,而不是空闲(我的意思是,在一次使用和另一次使用之间)。如果你没有释放那个在服务器端仍然被标记为忙的资源(这里我指的是该资源的服务器端表示),并且由于服务器通常只有有限数量的“插槽”,另一个客户端可能会看到拒绝新连接的请求,这是错误的,因为也许你实际上没有使用它。

答案 2 :(得分:0)

我终于有点工作了。最大的问题不是我第一次没有关闭连接,而是我没有正确地调用我的Asynctask。它必须是:

new MatchDetails().execute((Void) null);

现在唯一的问题是textViews在片段打开两次之前不会改变。我第一次打开它们时它们看起来是空的,但是当我再次打开它们时它们会变成它们应该是的。有没有人有任何想法?