如何使用spring实现lazy db data fetching

时间:2016-10-05 18:26:00

标签: java spring spring-data lazy-loading junit4

在描述我的问题之前,我想告诉你我是春天的新人。

所以在这里我只是将我的示例代码用于使用JDBCTemplate从db获取数据:

    SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
    dataSource.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
    dataSource.setUrl("jdbc:derby:C:/Users/mypc/Downloads/db-derby-10.12.1.1-bin/db-derby-10.12.1.1-bin/demo/databases/toursdb;create=true");
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    List<Map<String, Object>> rows = jdbcTemplate.queryForList("select * from " + tableName);
    dataSource.getConnection().close();
    System.out.println(rows);

所以在这里我将整个结果集放在Map中然后返回它。问题是它抛出大型数据集的java堆内存异常(正如我上面提到的发布代码是用于示例)。

现在我使用RowCallbackHandler()更改此实现。

所以我的修改后的代码现在是

            SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
            dataSource.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
            dataSource.setUrl("jdbc:derby:C:/Users/mypc/Downloads/db-derby-10.12.1.1-bin/db-derby-10.12.1.1-bin/demo/databases/toursdb;create=true");
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            jdbcTemplate.setFetchSize(200);
            jdbcTemplate.query("select * from " + tableName, new RowCallbackHandler() {
                public void processRow(ResultSet rs) throws SQLException {
                    Map<String, Object> rowInMap = new HashMap<String, Object>();
                    for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                        rowInMap.put(rs.getMetaData().getColumnName(i), rs.getObject(i));
                    }
                    System.out.println(rowInMap);
                }
            });
            dataSource.getConnection().close();

但问题是如何使用来自另一个类的另一个方法的rowcallbackhandler方法,它将懒惰地使用数据,显然它应该是线程安全的。它将用于JUnit测试。

1 个答案:

答案 0 :(得分:0)

您告诉jdbc驱动程序获取200和200的行。以下是Statement类java doc的解释。

/**
     * Gives the JDBC driver a hint as to the number of rows that should
     * be fetched from the database when more rows are needed for
     * <code>ResultSet</code> objects genrated by this <code>Statement</code>.
     * If the value specified is zero, then the hint is ignored.
     * The default value is zero.
     *
     * @param rows the number of rows to fetch
     * @exception SQLException if a database access error occurs,
     * this method is called on a closed <code>Statement</code> or the
     *        condition  <code>rows >= 0</code> is not satisfied.
     * @since 1.2
     * @see #getFetchSize
     */

您没有告诉延迟加载或过滤您的查询,您获取整个表。最简单的方法是使用where条件来过滤记录或使用分页功能。 对于oracle,您可以在查询中添加“where rownum&lt; 200”。 Spring jdbc基于获取记录,收集集合并返回。因此,当您收到List时,这意味着将从数据库中检索整个数据并关闭语句。您可以在RowCallbackHandler类中处理您的记录,但是在您的过程中,数据库语句和结果集将会打开。