2012-03-05 27 views
16

Tôi cần chèn hàng nghìn bản ghi vào cơ sở dữ liệu tại một thời điểm. Tôi đang sử dụng mẫu JDBC mùa xuân trong ứng dụng của mình.Làm cách nào để thực hiện nhiều lần chèn trong cơ sở dữ liệu bằng cách sử dụng hàng loạt Mẫu JDBC mùa xuân?

Dưới đây là mã tôi đã viết cho đến nay, thực hiện tất cả các lần chèn tại một lần. Vì vậy, nếu tôi ahve 10.000 người dùng họ được chèn vào một lần. Nhưng những gì tôi muốn là để thực hiện chúng theo lô nói ví dụ 500 hồ sơ trong một lô và như vậy.

@Override 
public void saveBatch(final List<Employee> employeeList) { 
    final int batchSize = 500; 

    getJdbcTemplate().batchUpdate(QUERY_SAVE, 
      new BatchPreparedStatementSetter() { 
       @Override 
       public void setValues(PreparedStatement ps, int i) 
         throws SQLException { 
        Employee employee = employeeList.get(i); 
        ps.setString(1, employee.getFirstname()); 
        ps.setString(2, employee.getLastname()); 
        ps.setString(3, employee.getEmployeeIdOnSourceSystem()); 
       } 

       @Override 
       public int getBatchSize() { 
        return employeeList.size(); 
       } 
      }); 

} 

Làm thế nào để thay đổi mã ở trên để thay vì employeeList.size() như kích thước hàng loạt, chúng tôi có thể có kích thước hàng loạt như nói 500, thực hiện chúng và sau đó tiếp theo 500 và vân vân?

Vui lòng trợ giúp.

+0

Tôi biết câu hỏi này là khá cũ, nhưng tôi có một câu hỏi. Tại sao bạn không trả lại 500 trong phương thức 'getBatchSize'? –

Trả lời

21

Tôi không chắc liệu bạn có thể làm điều đó bằng cách sử dụng mẫu JDBC một mình hay không. Có thể bạn có thể gọi phương thức batchUpdate trong các bước, bằng cách chia nhỏ danh sách lớn thành các khối có kích thước hàng loạt.

Có một cái nhìn ở đây:

@Override 
public void saveBatch(final List<Employee> employeeList) { 
    final int batchSize = 500; 

    for (int j = 0; j < employeeList.size(); j += batchSize) { 

     final List<Employee> batchList = employeeList.subList(j, j + batchSize > employeeList.size() ? employeeList.size() : j + batchSize); 

     getJdbcTemplate().batchUpdate(QUERY_SAVE, 
      new BatchPreparedStatementSetter() { 
       @Override 
       public void setValues(PreparedStatement ps, int i) 
         throws SQLException { 
        Employee employee = batchList.get(i); 
        ps.setString(1, employee.getFirstname()); 
        ps.setString(2, employee.getLastname()); 
        ps.setString(3, employee.getEmployeeIdOnSourceSystem()); 
       } 

       @Override 
       public int getBatchSize() { 
        return batchList.size(); 
       } 
      }); 

    } 
} 
14

Tôi biết đó là một hơi muộn nhưng bạn có thể làm điều gì đó tương tự như những gì @adarshr đang làm, ngoại trừ sử dụng Google Guava Lists.partition để có được các danh sách con.

public void saveBatch(final List<Employee> employeeList) { 
    final int batchSize = 500; 
    List<List<Employee>> batchLists = Lists.partition(employeeList, batchSize); 

    for(List<Employee> batch : batchLists) { 
     getJdbcTemplate().batchUpdate(QUERY_SAVE, new BatchPreparedStatementSetter() { 
      @Override 
      public void setValues(PreparedStatement ps, int i) 
        throws SQLException { 
       Employee employee = batch.get(i); 
       ps.setString(1, employee.getFirstname()); 
       ps.setString(2, employee.getLastname()); 
       ps.setString(3, employee.getEmployeeIdOnSourceSystem()); 
      } 

      @Override 
      public int getBatchSize() { 
       return batch.size(); 
      } 
     }); 
    } 
} 
0

cách Tuy đơn giản là thay đổi phương pháp getBatchsize() như trong hoạt động tốt dưới

Không cần phải phân vùng hay tập hợp con của danh sách :),

@Override 
public void saveBatch(final List<Employee> employeeList) { 
    final int batchSize = 500; 
    getJdbcTemplate().batchUpdate(QUERY_SAVE, 
      new BatchPreparedStatementSetter() { 
       @Override 
       public void setValues(PreparedStatement ps, int i) 
         throws SQLException { 
        Employee employee = employeeList.get(i); 
        ps.setString(1, employee.getFirstname()); 
        ps.setString(2, employee.getLastname()); 
        ps.setString(3, employee.getEmployeeIdOnSourceSystem()); 
       } 

       @Override 
       public int getBatchSize() { 
        if (batchSize > employeeList.size()) { 
         return employeeList.size(); 
        } 
        return batchSize; 
       } 
      }); 
} 
+0

Điều này sẽ không hoạt động, nhưng chỉ chèn 500 bản ghi đầu tiên vào DB. – ngeek

3
Spring provide Batch operations with multiple batches 
here 100 is batch size. 


public class JdbcActorDao implements ActorDao { 

    private JdbcTemplate jdbcTemplate; 

    public void setDataSource(DataSource dataSource) { 
     this.jdbcTemplate = new JdbcTemplate(dataSource); 
    } 

    public int[][] batchUpdate(final Collection<Actor> actors) { 
     int[][] updateCounts = jdbcTemplate.batchUpdate(
       "update t_actor set first_name = ?, last_name = ? where id = ?", 
       actors, 
       100, 
       new ParameterizedPreparedStatementSetter<Actor>() { 
        public void setValues(PreparedStatement ps, Actor argument) throws SQLException { 
         ps.setString(1, argument.getFirstName()); 
         ps.setString(2, argument.getLastName()); 
         ps.setLong(3, argument.getId().longValue()); 
        } 
       }); 
     return updateCounts; 
    } 

    // ... additional methods 

} 
+0

Cảm ơn bạn đã phản hồi. Nó trông sạch hơn nhiều. Tôi đã có vài nghi ngờ: 1) ý nghĩa của mảng 2D như là phản ứng của phương pháp batchUpdate 2) Chúng ta có thể kiểm tra chéo trong quá trình chạy ứng dụng mà dboperations thực sự đang chạy theo lô không? – Ankit

Các vấn đề liên quan