2017-01-31 9 views
0

Я пытаюсь реализовать разбиение на страницы с помощью java jdbc. Мой запрос принимает ограничение, которое представляет собой размер партии и смещение.Реализовать разбиение на страницы с использованием смещения в java jdbc

Как увеличить смещение после завершения каждой партии. Я не могу понять, как я могу использовать это смещение для достижения функциональности. Я попытался написать метод-обертку, который рекурсивно вызывает метод, который принимает смещение.

Вот мой запрос

select 
ECId,InvId,ApplianceId,ProgName,CollectStartTS,CollectEndTS,CRPartyId, 
HostName,IPAddess,SoftwareVer,OsType,collectserialnum, 
CollectProductId,SNMPLoc,HWAlertCnt,SWAlertCnt,UploadProcEndTS 
from inventory_details 

и код

public void getInventory() throws SQLException { 
    int batch = Integer.parseInt(PropertyFileReader.getInstance() 
     .getProperty("BATCHSIZE")); 
    int offset= 0; 
    while(offset<batch){ 
     DrillDAO dao = new DrillDAO(); 
     dao.getAllInventoryDetails(offset); 
    } 
    offset = offset+batch+1; 
} 

public ArrayList<InventoryDetail> getAllInventoryDetails(int offset) 
      throws SQLException {    
    int batchSize = Integer.parseInt(PropertyFileReader.getInstance() 
        .getProperty("BATCHSIZE"));    

    ArrayList<InventoryDetail> inventoryDetailList = new ArrayList<InventoryDetail>();    

    Connection connection = null; 
    Statement statement = null; 
    ResultSet resultset = null; 
    try { 
     Class.forName(getJdbcDriver()); 
     connection = DriverManager.getConnection(
        getJdbcURL(), getUserName(), getPassword()); 
     statement = connection.createStatement(); 
     LOGGER.info("Start time " + CPUUtils.getCpuTime()); 
     resultset = statement.executeQuery(getQuery() 
        + " " + "LIMIT" + " " + batchSize + " " 
        + "OFFSET" + " " + offset); 
     LOGGER.info("End time " + CPUUtils.getCpuTime()); 

     while (resultset.next()) { 
      InventoryDetail id = new InventoryDetail(); 
      id.setEcId(resultset.getString(1)); 
      id.setInvId(resultset.getString(2)); 
      id.setApplianceId(resultset.getString(3)); 
      id.setProgName(resultset.getString(4)); 
      id.setCollectStartTS(resultset.getString(5)); 
      id.setCollectEndTS(resultset.getString(6)); 
      id.setCrPartyId(resultset.getString(7)); 
      id.setHostName(resultset.getString(8)); 
      id.setIpAddess(resultset.getString(9)); 
      id.setSoftwareVer(resultset.getString(10)); 
      id.setOsType(resultset.getString(11)); 
      id.setCollectSerialNum(resultset.getString(12)); 
      id.setCollectProductId(resultset.getString(13)); 
      id.setSnmpLoc(resultset.getString(14)); 
      id.setHwAlertCnt(resultset.getString(15)); 
      id.setSwAlertCnt(resultset.getString(16)); 
      id.setUploadProcEndTS(resultset.getString(17)); 
      inventoryDetailList.add(id); 
     } 
    } catch (SQLException se) { 
     se.printStackTrace(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      if (statement != null) 
       statement.close(); 
     } catch (SQLException se2) { 
     } 
     try { 
      if (connection != null) 
       connection.close(); 
     } catch (SQLException se) { 
      se.printStackTrace(); 
     } 
    } 
    return inventoryDetailList; 
} 
+1

Pagination не имеет смысла, если вы не укажете какой-либо порядок для набора результатов, то есть объявите 'ORDER BY' в запросе. Как следует упорядочивать строки? –

ответ

0

Вы можете написать обертку, как показано ниже:

public List<InventoryDetail> getInventory() throws SQLException { 
     int batch = Integer.parseInt(PropertyFileReader.getInstance().getProperty("BATCHSIZE")); 
     int offset= 0; 

     List<InventoryDetail> finalList = new ArrayList<InventoryDetail>(); 

     DrillDAO dao = new DrillDAO(); 
     for(int i = offset; ; i += batch+1) { 
      //request data with one more, if exact that count return, you will know more data exist 
      //so you can continue; when less than that return, you will know no more data, so break the loop 
      ArrayList<InventoryDetail> invList = dao.getAllInventoryDetails(i, batch + 1);    
      if (invList.size() <= batch) {     
       break; 
      } else { 
       //remove the extra one called cz it will get in next call 
       invList.remove(invList.size() - 1);     
      } 
      finalList.addAll(invList); 
     } 

     return finalList; 
    } 

Изменение

public ArrayList<InventoryDetail> getAllInventoryDetails(int offset) 
      throws SQLException { 

к

public ArrayList<InventoryDetail> getAllInventoryDetails(int offset, int batchSize) 
      throws SQLException { 

и удалите следующую строку внутри него.

int batchSize = Integer.parseInt(PropertyFileReader.getInstance() 
        .getProperty("BATCHSIZE")); 
0

Во-первых, вы должны получить счетчик селектов:

String countQuery = "SELECT COUNT(0)\n" + 
    "FROM INVENTORY_DETAILS"; 

Теперь, когда у вас есть ваш размер результата, спросите, если он больше, чем 0, таким образом, вы не должны выполнить команду Исходный запрос зря:

// here goes the statement declaration and execution 
long count = statement.execute(countQuery); 
List<InventoryDetail> inventoryDetailList = new ArrayList<InventoryDetail>(); 

if (count > 0) { 
    String query = "SELECT ECID,INVID,APPLIANCEID,PROGNAME,COLLECTSTARTTS,COLLECTENDTS,CRPARTYID,\n" + 
     " HOSTNAME,IPADDESS,SOFTWAREVER,OSTYPE,COLLECTSERIALNUM,\n" + 
     " COLLECTPRODUCTID,SNMPLOC,HWALERTCNT,SWALERTCNT,UPLOADPROCENDTS\n"+ 
     "FROM INVENTORY_DETAILS\n"; 

Наконец, и это является наиболее важной частью команды, вы будете перебирать над пагинацией:

long page = 1; 
    long limit = page * offset; 
    long loops = (count - (count % limit))/offset; 

    for (; page <= loops; page++) { 
     if (page == 1) { 
      query += "LIMIT " + limit; 
     } else { 
      limit = page * offset; 
      query += "LIMIT " + limit + " OFFSET " + offset; 
     } 

     // here goes the statement declaration and execution 
     statement.execute(query); 
     // here goes the result set iteration and then... 
     inventoryDetailList.add(id); 
    } 
} 

Надеюсь, что это поможет.

+0

Поскольку в запросе не задано упорядочение строк, ничто не гарантирует, что одна и та же строка не отображается на более чем одной странице. –

+0

Да, я знаю, но для этого короля реализации требуется больше объяснений и сложностей для добавления, поскольку для этого требуется динамическое разбиение на страницы в зависимости от того, какое поле добавлено в порядок строк. Мое намерение здесь просто подсказывало, как реализовать простую разбивку на страницы. Любой может проверить эту [реализацию] (https://github.com/spring-projects/spring-batch/blob/master/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/ support/SqlWindowingPagingQueryProvider.java) из проекта Spring, который объясняет мой предыдущий комментарий. –