【问题标题】:Avoiding JDBC call避免 JDBC 调用
【发布时间】:2011-08-26 12:27:14
【问题描述】:

场景是这样的:

for loop // runs say 200000 times
{
    // here, i do a select from a database, fetching few rows which are expected to increase with every new iteration of for loop
    // currently i am doing this select using simple JDBC call (using JDBC only is NOT a requirement)

    // then i do some string matching stuff and then i either insert or update a particular row (in 95% cases i will insert)
    // this insert or update is being done using Hibernate (using Hibernate over here is a requirement)
}

所以问题是,在每个循环中,我都必须考虑每个先前插入/更新的行。由于这个要求,我必须在每个循环中进行一次 JDBC 调用。而且这个 JDBC 调用占用的时间最长,降低了性能。

我想知道,是否有任何方法可以让我不必在每次迭代中进行 JDBC 调用,但我仍然可以考虑所有记录,包括之前插入/更新中的记录?像缓存或一些内存数据结构或类似的东西?

代码如下:

for loop // runs say 2000 times
{
    String query = pdi.selectAllPatients(patientInfo);
    Statement st = conn.createStatement();
    ResultSet patientRs = st.executeQuery(query);

    while (patientRs.hasNext())
    {
        // some string ops
    }

    // Create session for DB No.2
    Session sessionEmpi = sessionFactoryEmpi.getCurrentSession();
    sessionEmpi.beginTransaction();

    if(some condition)
        patientDao.insertPatient(patientInfo, sessionEmpi);
    else
        patientDao.insertref(patientInfo.getref(), sessionEmpi);

    conn.commit();
}

public int insertPatient(PatientInfo input, Session session) throws SQLException {

    try {

        session.save(input.getPatient());
        session.flush();
        session.save(input.getref());
        session.getTransaction().commit();

        return 1;

    } catch (Exception ex) {
        session.getTransaction().rollback();
        ex.printStackTrace();
        return 0;
    }
}

【问题讨论】:

  • 你确定你在java中使用nhibernate吗?
  • 我使用的是 Hibernate,而不是 nhibernate。
  • 那么不要标记nhibernate。我删除了它。至于具体问题,您是否使用连接池?获取非池化连接至少需要 200ms,获取池化连接基本上是无操作的。
  • 你不能再贴一些代码吗?也许有更快的算法来做你想做的事。
  • @BalusC:是的,先生,我以前没有使用过连接池。我并没有忽略你的问题,只是参与了其他事情,对此感到抱歉。请您进一步阐明您的观点吗?

标签: java performance hibernate jdbc


【解决方案1】:

SELECT 的性能是否一致?除非您的数据非常小,否则您可能无法将所有更改缓存在内存中。您还可以批处理 SELECT,有效地展开循环。

【讨论】:

    【解决方案2】:

    您可以使用 PreparedStatement 接口代替 Statement 接口,因为它避免了将查询触发到数据库的不必要调用,您只需将数据绑定到 for 循环中,这将帮助您提高性能!!

    示例:

    PreparedStatement s =con.prepareStatement("select * from student_master where stu_id = ?");
    
    for()
    {
       s.setString(1,"s002");
       ResultSet rs = s.executeQuery();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多