简体   繁体   中英

Which Place to write connection.close() and preparedstatement.close()

I am new in JDBC ...

Student class has methods like Constructor, add(),update() and delete() etc ...

Open a Connection in Constructor. Which Place to write conn.close() and pstmt.close() in below code Help Me

class Student
{
    Connection conn;

    PreparedStatement  pstmt;

    ResultSet rs;

    public Student()
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");

            conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");
        }
        catch(Exception e)
        {
             System.out.println("Error :"+e.getMessage());
        }

    }


    public void add(int rollno,String name)
    {
        try
        {
            pstmt = conn.prepareStatement("insert into student values (?, ?)");

            pstmt.setInt(1,rollno);

            pstmt.setString(2, name);

            int i = pstmt.executeUpdate();

            if (i != 0) {
                System.out.println("Record Inserted");
            } else {
                System.out.println("Record Not Inserted");
            }

        }
        catch(Exception e)
        {
             System.out.println("Error :"+e.getMessage());
        }

    }

    public void update(int rollno,String name)
    {
        try
        {
            pstmt = conn.prepareStatement("update student set name=? where rollno=?");

            pstmt.setString(1, name);

            pstmt.setInt(2,rollno);


            int i = pstmt.executeUpdate();

            if (i != 0) {
                System.out.println("Record Updated");
            } else {
                System.out.println("Record Not Updated");
            }


        }
        catch(Exception e)
        {
             System.out.println("Error :"+e.getMessage());
        }
    }

    public void delete(int rollno)
    {
        try
        {
            pstmt = conn.prepareStatement("delete from student where rollno=?");

            pstmt.setInt(1,rollno);


            int i = pstmt.executeUpdate();

            if (i != 0) {
                System.out.println("Record Deleted");
            } else {
                System.out.println("Record Not Deleted");
            }

        }
        catch(Exception e)
        {
             System.out.println("Error :"+e.getMessage());
        }
    }

}

Based on the sample code that you have posted, it seems all the operations that your trying to do like Add Update and Delete all use the same connection object created globally and initialized in your constructor "Student()". This is not a standard practice

As per standards you should not do that, you should create new connections as local variables on each of the operations like 'add', 'update' and 'delete' seperately

Also keep in mind if your are using 'Bean managed transaction' then you need to commit the transaction before closing it.Or else add conn.commit(); in the finally block

Here is a quick example on how a your method should be

public void add(int rollno,String name)
{
    Connection conn = null;
    PreparedStatement pstmt = null;
    try
    {
        pstmt = conn.prepareStatement("insert into student values (?, ?)");

        pstmt.setInt(1,rollno);

        pstmt.setString(2, name);

        int i = pstmt.executeUpdate();

        if (i != 0) {
            System.out.println("Record Inserted");
        } else {
            System.out.println("Record Not Inserted");
        }

    } catch(Exception e) {
         System.out.println("Error :"+e.getMessage());
    } finally {
         if(pstmt!=null) {
             pstmt.close();
         }
         if(conn!=null) {
             conn.comit(); // Add this line ONLY if you use bean managed transaction
             conn.close();
         }
    }

}

I guess you should add another method to close the connection, and just invoke it on your object when you are done with operations.

public void closeConnection() {
    conn.close();
}

Also it would be good idea to create another method to open connection, not to open it from constructor.

First of all, I wouldn't open the connection in the constructor, since it can lead to many connections being open for a long time without being used, and since connections are a limited resource, you should keep them open for as little time as possible.

I would open and close the connection (and the prepared statements) in each method that uses it ( add , update , delete , etc...). This way the connection would only be open when it is needed.

You can either use a try-catch-finally block and close the connection within the finally.

Connection con;
try
{
  con = new Connection(...);
}
catch (Exception e)
{
 //Error Handling
}
finally
{
  connection.close();
}

Or you use a try-with-resource and let the VM take care of closing the connections (In this case, you do not need to declare the Connection as field but have one for each action):

try(Connection con = new Connection(...))
{

}
catch()
{

}

Add a finally block after the catch blocks to close the PreparedStatement and Connection object. Something like

catch (Exception d) {
   //do whatever you want when exception occurs
}
finally {
    //close resultset
    //close prepared statement
    //close connection object
}

finally ensures that the resources are closed before the control returns. Resources will be closed even if you are using return inside the try block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM