当前位置: 首页 > 面试题库 >

良好做法:JDBC连接

阎卓
2023-03-14
问题内容

我已经为JDBC连接编写了一个简单的包装程序,它可以工作,但是我想通过最佳实践来对其进行改进。它基本上有类似的方法open()close()isOpened()select()insert()update()delete()batch()。为简单起见,我仅在此处发布前4种方法。

public class Query{
    private Connection con;
    private PreparedStatement ps;
    private ResultSet rs;

    //Database.open() returns a Connection ready to use
    public void open (Database database) throws DatabaseException, SQLException{
        if (!isOpened ()){
            con = database.open ();
        }
    }

    public void close () throws SQLException{
        if (isOpened ()){
            if (ps != null) ps.close ();
            con.close ();
            con = null;
        }
    }

    public boolean isOpened (){
        return con != null;
    }

    //The query string is the query without the word "select" and can use placeholders (?)
    //The args param it's just an array owith the values of this placeholders
    public ResultSet select (String query, Object[] args) throws SQLException{
        if (ps != null) ps.close ();

        if (isOpened ()){
            ps = con.prepareStatement ("select " + query);
            if (args != null){
                for (int i=0; i<args.length; i++){
                    ps.setObject (i+1, args[i]);
                }
            }
            rs = ps.executeQuery ();
        }

        return rs;
    }
}

笔记:

  • 可以重复使用同一查询对象,例如打开和关闭它,以及在再次打开之后。
  • 我不是关闭每个查询的连接,而是关闭准备好的语句(这是正确的,或者我可以让准备好的语句保持打开状态,因为Connection对象会关闭它吗?)
  • 当我关闭时Connection,所有PreparedStatements和它们的ResultSets也都关闭了,对吗?

用法:

Database database;

//Database initialization

Query query = new Query ();


query.open (database);

ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" });
doSomethingWithResult1 (rs);

//Connection is not closed here

ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 });
doSomethingWithResult2 (rs);

query.close ();


query.open (database);

ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" });
doSomethingWithResult1 (rs);

//Connection is not closed here

ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 });
doSomethingWithResult2 (rs);

query.close ();

你怎么看?每次查询后都应该关闭并打开连接吗?在同一连接上进行每个查询后,是否可以打开PreparedStatement?这是一个好的设计?


问题答案:

使用完PreparedStatement之后,必须在同一连接上创建新的PreparedStatement之后,再关闭它。我遇到了严重的问题,因为我没有关闭PreparedStatements。事实证明,在数据库服务器上,只有在显式调用PreparedStatement.close()之后才释放已分配的资源。

如bdares所评论,应尽可能不频繁地打开和关闭Connection。



 类似资料:
  • 问题内容: 过去,我使用以下方法读取大量代码: 这样做是惯例吗? 优点和缺点是什么? 在我看来,这就像完成异常的“ Agent Orange”方式 编辑 处理方法中的预期异常 引发意外异常(一对一) 不在乎错误 那是路要走吗? 问题答案: 你不应该扔。这就是为什么。 Throwable是可抛出的事物层次结构的顶部,由and组成。由于根据定义是由不可挽救的条件引起的,因此将它们包括在方法声明中是没有

  • 我正在使用Laravel5.6作为我个人项目的后端,我一直在做一些(对我来说)似乎是不好的做法,不管怎样,我想知道它是否真的那么糟糕。 首先,我使用的是Vue。js(CLI 3)项目作为客户端,我正在向我的Laravel后端发出请求。现在,为了处理通知/祝酒,我使用下一种格式: 不管我做得对还是错,我总是用同样的格式和

  • 问题内容: 我想知道创建Javadocs时的最佳实践。我有一个包含许多文件的项目。代码已由许多开发人员创建。每个文件都有一个注释,因此很明显谁创建了一个特定的类。 但是,当其他一些开发人员将新代码添加到文件中,对其进行修改等时,他应该如何告知团队的其他成员他已经创建了一些新功能或已经修改了现有代码?换句话说,我们应该如何“使Javadocs与现实兼容”?;) 将他的名字添加到现有标签中?然后,如果

  • 问题内容: 缩进SQL语句的公认做法是什么?例如,考虑以下SQL语句: 应该如何缩进?非常感谢。 问题答案: 我喜欢将所有的“,”放在前面,这样,当SQL编辑器在X行出现错误时,我就永远不会搜索它们。 对于那些不使用这种类型的编写SQL语句的人来说,这是一个示例。两者都包含缺少逗号的错误。 在第一个示例中,我发现更容易,更快捷。希望本示例向您展示更多我的观点。

  • 微服务的宗旨之一是它们是独立开发和部署的,有些人甚至说微服务必须使用不同的表才能真正解耦和独立。 因此,当我们谈论使用微服务暴露的业务时,它并不完全正确。如果您有一个标准化的数据库和一个用户表,另一个用于用户地址,因为一个用户可能有一个或多个地址(住宅、商业...)和另一个用于电话的表,原因与微服务os客户端使用多个表的原因相同。1-在这种情况下,我们仍然可以将其归类为微服务?(也许我对微服务的理

  • 问题内容: 我最近阅读了很多有关Linux上共享库的信息,这是我所学到的: 共享库应嵌入,包括其主要版本号。就像是: 其实际文件名还应包含次要版本号。就像是: 当库文件复制到,比方说,如果运行时,它会读取,创建一个名为符号链接指向。 如果要使用此库进行开发,则应首先创建一个指向实际文件的没有任何版本号的符号链接。这通常由 开发 包(打包库时)完成。 它是否正确 ? 问题答案: 建议阅读: Ulri