java - 关于正确关闭/提交数据库事务和执行查询的问题

标签 java coding-style

我正在更新一个项目,我只想知道这两个问题的最佳实践:

  1. 我应该继续使用 Connections/Statements/ResultSet 来执行查询还是应该使用其他东西?
  2. 这是提交/关闭连接/语句/结果集的正确方法吗?我的意思是我是否以正确的顺序在正确的位置使用 try/catch/finally block 执行提交/关闭?

请提供这些片段的修改代码示例以阐明您的观点。

来自 select 类型方法的代码片段:

public  ArrayList getMethod() {

    ArrayList a = new ArrayList();

    Connection con = null;
    ResultSet rs = null;
    Statement stmt = null;

    try {

        con = BoneCPConnection.getConnectionPool().getConnection();     // get a connection
        con.setAutoCommit(true);            
        stmt = con.createStatement();

        String query = "select * from example";

        rs = stmt.executeQuery(query);

        while(rs.next()) {
            System.out.println("Result: "+ rs.getInt(1));
        }

    } catch (Exception e) {
        System.out.println("Issue with getMethod");
        e.printStackTrace();
    } finally {

        try {
            rs.close();
            stmt.close();
            con.close();
        } catch (Exception e) {
            con = null;
        }

        rs = null;
        stmt = null;
        con = null;
    }

    return a;
}

来自 update 类型方法的代码片段

public void updateMethod() {

    ArrayList a = new ArrayList();

    Connection con = null;
    Statement stmt = null;
    int updateCount = null;

    try {

        con = BoneCPConnection.getConnectionPool().getConnection();     // get a connection     
        stmt = con.createStatement();

        String query = "update example set id = 1";

        updateCount = stmt.executeUpdate(query);

        System.out.println("Result: "+ updateCount);    

    } catch (Exception e) {
        System.out.println("Issue with updateMethod");
        e.printStackTrace();
    } finally {

        try {
            con.commit();
            stmt.close();
            con.close();
        } catch (Exception e) {
            con = null;
        }

        stmt = null;
        con = null;
    }
}

最佳答案

至少,您应该切换到 PreparedStatement 而不是普通的 Statements。这样做的原因是,在大多数情况下,JDBC 驱动程序会在创建时将语句发送到数据库,以便对其进行预编译。然后您可以将参数绑定(bind)到语句并执行。除了预编译的性能优势之外,您还可以一点 防止 SQL 注入(inject)攻击,因为您设置参数的方式是更强类型的。有个好description Oracle 网站上准备好的语句。

如果您正在使用 Spring(或想跳槽将其添加到您的系统中),您可以查看 JdbcTemplateJdbcDaoSupport 类(都概述了 here )。主要优点是它会为您处理连接清理代码(因此您不必担心错过 close 调用)。

同样,如果您将 Spring 添加到您的项目中,您可以考虑使用它来配置您的事务(通过注释或使用 Spring 上下文文件)。这将使您能够将事务管理从实际实现中拉出来,并使您的 Dao 中的代码更加简洁。

至于您对提交/关闭的处理:您应该将您的提交语句移出您的 finally block 并进入主执行路径。您应该将 close 语句保留在 finally block 中,因为无论如何您都希望确保它们发生。

使用 PreparedStatements 更新代码的示例如下:

public void updateMethod() {
    Connection con = null;
    PreparedStatement stmt = null;
    int updateCount = null;

    try {
        con = BoneCPConnection.getConnectionPool().getConnection();
        stmt = con.prepareStatement("update example set id = ?");        
        stmt.setInt(1,1);
        updateCount = stmt.executeUpdate(query);
        con.commit();
    } catch (Exception e) {
       if(con != null){
        con.rollback();
       }
    } finally {

        try {
          if(stmt != null){
            stmt.close();
          }
          if(con != null){                
            con.close();
          }
        } catch (Exception e) {
            con = null;
        }        
    }
}

如果您使用的是 Spring 的 JdbcDaoSuport,它看起来像:

public class YourDao extends JdbcDaoSupport{

  public void updateMethod(){
    String sql = "update example set id = ?";
    getJdbcTemplate().update(sql, new Object[] { new Integer(1)});           
  }

}

关于java - 关于正确关闭/提交数据库事务和执行查询的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7972594/

相关文章:

ruby - Ruby : Should we really believe the style guide? 中的失败与提升

sql-server - SQL Server 代码审查和最佳实践的资源

php - spaghetti php的定义?

java - maven测试报告格式

java - 在 2 台 PC 之间创建信任证书

java - 无法单击日期选择器按钮来使用 appium 和 java 更改日期

c# - 编写修改 C# 集合的方法时有什么好的做法

c - 指针约定与 : Array of pointers to certain elements

java - 关于extern "C"的C++到Java的转换问题

java - 非静态方法可以修改静态变量吗