2016-10-05 3 views
3

Прежде чем описывать мою проблему, я хочу сообщить вам, что я новичок весной.Как реализовать lazy db data fetching using spring

Так вот я просто кладу пример кода, что я делаю для выборки данных из БД с помощью JdbcTemplate:

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); 

Так вот я вложил в ResultSet карту, а затем вернуть его. Проблема заключается в том, что он выбрасывает исключение памяти кучи 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 метод из другого метода из другого класса, который будет потреблять данные lazyly и, очевидно, она должна быть поточно. Он будет использоваться для теста JUnit.

+0

'потребляйте данные лениво'. Я не думаю, что это означает, что вы думаете, что это значит. То, что вам кажется нужным, является пакетной, то есть потребительский код извлекает данные партиями определенного фиксированного размера (например, 20, 50, 100 независимо) и обрабатывает их в кусках. – Taylor

+0

да, я точно хочу заполнить мою карту с 20 данными, а затем обработать ее снова bck до результата, чтобы получить часть, и она заполнит карту следующими 20 данными. – saba

+0

Я еще раз говорю, что вы занимаетесь дозированием с помощью шаблонов jdbc. – Taylor

ответ

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 
    */ 

Вы не говорите ленивую загрузку или фильтрацию по вашему запросу, вы получаете всю таблицу. Самый простой способ - использовать условия для фильтрации ваших записей или использования функции разбиения на страницы. Для оракула вы можете добавить «где rownum < 200» на ваш запрос. Spring jdbc основан на извлечении записей, сборе внутри коллекции и возврате. Поэтому, когда вы получаете свой список, это означает, что все данные извлекаются из базы данных, а оператор закрыт. Вы можете обрабатывать свою запись внутри класса RowCallbackHandler, однако во время процесса будет открыто заявление базы данных и набор результатов.

+0

Согласно вашему предложению, если я ставлю rownum для oracle или top для sql-сервера, я не могу получить все данные, но мне нужны все данные для проверки с моим ожидаемым. – saba

+0

, поэтому вам нужно отфильтровать свои данные с помощью предложения where в вашем sql. Рядом с oracle rownum не гарантируется получение одинаковых данных каждый раз. – ibrahimbayer

+0

Спасибо за ваши комментарии, но есть ли способ вернуть кусок карты и подтвердить это, и если не найден желаемый результат, снова вызовите его и верните следующий фрагмент карты из того же набора результатов, что и возврат доходности. – saba