我又來了,又是百萬數據的導入,其實又是項目中遇到的,那麼怎麼快速導入呢,由於咱們項目用的是JPA,有時也使用jdbcTemplate,沒錯又是jdbcTemplate。對於這種大數據的處理,咱們能業務代碼方面最基本的能想到的就是塊處理和使用線程。此處能夠參考JAVA向Mysql插入億級別數據---測評java
首先因爲咱們項目用的是jpa,so我最早也使用的jpa來存數據,並且最早作的也是批量處理,一次存10000數據。在springboot1.5中,jpa的save有兩個方法,先來看一下源碼:mysql
@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S var1);
<S extends T> Iterable<S> save(Iterable<S> var1);
}
複製代碼
能夠看到save既能夠保存一個實體,也能夠保存多個實體,因此我選擇的就是保存多個實體,結果發現save的速度賊慢,尤爲是想存100000條數據時。而若是我save單個實體,並開啓多線程,發現save的效率比批量處理要快點,我也是懵了。一開始就這樣存80多萬的數據用了N久,具體時間也沒記錄了。spring
而後本身就想着用最原生的方法來存一下,就是jdbc,一樣一次存10000條,批量處理。sql
首先要注意的是:
1.在URL鏈接時須要開啓批處理、以及預編譯
String url = 「jdbc:mysql://localhost:3306/cds_credit_rtm_data?rewriteBatched
-Statements=true&useServerPrepStmts=false」;數據庫
- PreparedStatement預處理sql語句必須放在循環體外
接下來就是常規的jdbc操做:springboot
//開始總計時
long bTime1 = System.currentTimeMillis();
//count=1380271
for (int i=0; i<count; i+=100000){
List<DataToEmployee> list = //todo 每次從數據庫獲取10w條
Connection conn = null;
PreparedStatement pstm = null;
try{
//加載jdbc驅動
Class.forName("com.mysql.jdbc.Driver");
//鏈接mysql
conn = DriverManager.getConnection(url, user, password);
String sql = "....."; //insert語句
//關閉自動提交
// conn.setAutoCommit(false);
//預編譯sql
pstm = conn.prepareStatement(sql);
if(list!=null && list.size()>0){
long bTime = System.currentTimeMillis();
for(DataToEmployee data : list){
pstm.setString(1,data.getName());
......
pstm.addBatch(); //批量處理
}
pstm.executeBatch();
//關閉分段計時
long eTime = System.currentTimeMillis();
//輸出
System.out.println("成功插入10W條數據耗時:"+(eTime-bTime));
}
}
}
//關閉總計時
long eTime1 = System.currentTimeMillis();
//輸出
System.out.println("插入"+count+"數據共耗時:"+(eTime1-bTime1));
複製代碼
這裏統計出插入10W條數據的時間通常維持在2s左右,相比以前jpa是有很大的提高多線程
成功插入10W條數據耗時:2832
成功插入10W條數據耗時:1870
成功插入10W條數據耗時:2328
成功插入10W條數據耗時:2023
成功插入10W條數據耗時:2148
成功插入10W條數據耗時:1789
成功插入10W條數據耗時:1987
成功插入10W條數據耗時:2032
...大數據
jpa在存大量數據的時候,須要進行ORM轉換,MyBatis也同樣,效率相比jdbc確定要差點,並且在使用jdbc的時候我就用了單線程,可見二者之間的差距。ui