【问题标题】:Approach to JDBC connections in a Servlet/JSP applicationServlet/JSP 应用程序中的 JDBC 连接方法
【发布时间】:2014-03-16 15:42:05
【问题描述】:

我有一些现有的 java 代码,以一些 DAO 类的形式,例如

class EmployeeDao {    

   public EmployeeDao(Connection conn) {
      // Prepare statements to be used by the methods below
   }

   public Employee getEmployeeById(long id) {
   }

   public Collection<Employee> getEmployeesByDepartment(long departmentId) {
   }
   ...
}

所有 DAO 类都是使用 JDBC 连接构建的。构造器准备方法所需的任何语句。这在单线程环境(例如批处理)中运行良好,调用者可以创建连接并使用该连接实例化所需的 Dao 对象。

我希望能够在 Java Web 应用程序中使用它,但我只是不确定如何处理 JDBC 连接。以下是一些想法:

  1. 每个请求都会创建一个新的 JDBC 连接并实例化所需的 Dao 对象。连接创建和 Dao 实例化显然都很昂贵

  2. 每个请求都从 JNDI 数据源获取连接并实例化所需的 Dao 对象。这消除了连接创建的开销,但保留了准备所有语句的开销

  3. 每个请求都从 JDNI 数据源获取连接并实例化所需的 Dao 对象,但语句不再由构造函数准备,它们是根据需要延迟准备的。

  4. HttpSessionListener 实例化 Dao 对象并将它们存储在会话中(使用 setAttribute)。当会话到期时,连接关闭。

  5. 创建无状态会话 bean。 bean 将实例化所需的 Dao 对象。

选项 1 不是真正的竞争者,它只是展示我的思考过程。

选项 2 和 3 可行,但似乎不是最佳选择,必须为每个请求准备语句似乎是一种开销,应该很容易避免,但我认为我错过了如何

选项 4 避免了在每次调用时准备语句的开销,但以手动维护状态为代价。我认为这不是 Servlet/JSP 应用程序中的预期使用模式(长时间保持连接)。

选项 5 应该可以工作,但似乎开销很大,这意味着我需要一个完整的 EJB 容器而不是一个简单的 servlet 引擎。

考虑到以下目标,哪些方法对人们有效:

  1. 尽可能避免为每个请求准备声明
  2. 最好使用简单的 servlet 引擎

PS:我知道 Hibernate 和 Entity Beans 等框架可以将其中的一些抽象出来,但我想理解“无框架”的基本情况。

【问题讨论】:

    标签: java jsp servlets jdbc


    【解决方案1】:

    我建议您使用在每个主要应用程序服务器中都可以找到的数据库连接池(或任何体面的实现,如 dbcp、c3p0 等)

    Spring 可以很好地在(或多或少)缓存的 dao 实例中注入对数据源的引用,因此您可以提高一点性能(在时间和内存消耗方面)。

    但是,我会说您每次都准备好您的语句并且不要尝试缓存它们,因为它们仍然链接到创建它们的连接,并且这些连接由数据源管理。

    最后,关于您对准备声明时间的担忧:如果您仔细编写查询,这可以忽略不计。时间没有花在准备报表的行为上;真正重要的是查询计划,它在数据库中完成,在幕后。这就是您“第一次”执行查询可能看起来更耗时的原因。但是,如果您将参数化查询写入语句,数据库将缓存您的查询执行计划,并在之后的每个查询执行中重用它。例如:

    PreparedStatement stmt =  conn.prepareStatement("select name from employees where number = ?");
    

    是可缓存的,每次你准备这个语句时查询计划都会被重用(数据库“记住”它为另一个语句准备了它)

    但是,这个:

    PreparedStatement stmt =  conn.prepareStatement("select name from employees where number = " + employeeNumber);
    

    意味着每次准备语句时,您的数据库都必须准备不同的执行计划(它不会“记住”该查询)-性能问题将在于我构建查询而不是 java 的方式语句对象。更不用说这种方式是不安全的,而且还容易发生 SQL 注入。

    希望对你有用

    【讨论】:

    • 谢谢,特别是关于缓存查询计划的一点,我还没有完全注册。
    猜你喜欢
    • 2014-03-31
    • 1970-01-01
    • 2017-04-15
    • 2012-06-25
    • 1970-01-01
    • 2011-06-13
    • 2016-02-01
    • 2012-03-02
    相关资源
    最近更新 更多