2013-03-09 7 views
5

Sto cercando modi diversi per eseguire l'inserimento di massa nel database (ad esempio SQL Server 2012) da un'applicazione Java. Ho bisogno di inserire molte entità nel database in modo molto efficiente senza fare tante chiamate al database quante sono le entità.Diversi modi per eseguire l'inserimento di massa nel database da un'applicazione java

Il mio requisito è eseguire un inserimento di massa di entità, in cui un inserto di entità nel database potrebbe comportare l'inserimento di dati in una o più tabelle. Di seguito sono le due vie che mi viene in mente:

  1. generare dinamicamente un batch di istruzioni SQL ed eseguirlo sul database facendo uso di supporto JDBC nativo.

  2. Costruire la rappresentazione XML di tutte le entità e quindi richiamare una stored procedure passando l'XML generato. La stored procedure si occupa di analizzare l'XML e inserire le entità nel database.

Sono nuovo di Java e non ho una conoscenza sufficiente dei framework disponibili. IMO, i due precedenti metodi sembrano essere molto ingenui e non fare leva sui quadri disponibili. Chiedo agli esperti di condividere diversi modi per ottenere inserimenti di massa insieme ai suoi pro e contro. Sono aperto a MyBatis, Spring-MyBatis, Spring-JDBC, JDBC, ecc. Che risolve il problema in modo efficiente.

Grazie.

+0

È possibile provare l'esecuzione in batch, come mostrato nell'esempio di codice 'demo' pubblicato in una delle risposte, e vedere se funziona abbastanza veloce per voi. – Eran

+0

@Eran: Sì, certo. –

risposta

1

è possibile personalizzato il codice con JDBC, non v'è alcun supporto quadro vostra esigenza

9

Ho un demo, JDBC elaborazione in batch di file : demo.txt Il contenuto

1899942, demo1
1.899.944 , Demo2
1.899.946, demo3
1.899.948, demo4

inserire i dati legge il contenuto del file

il mio codice:

public class Test2 { 
     public static void main(String[] args) { 
      long start = System.currentTimeMillis(); 
      String sql = "insert into mobile_place(number,place) values(?,?)"; 
      int count=0; 
      PreparedStatement pstmt = null; 
      Connection conn = JDBCUtil.getConnection(); 
      try { 
       pstmt = conn.prepareStatement(sql); 

       InputStreamReader is = new InputStreamReader(new FileInputStream(new File("D:/CC.txt")),"utf-8"); 
       BufferedReader br = new BufferedReader(is); 
       conn.setAutoCommit(false); 

       String s1 = null; 
       String s2 = null; 
       while(br.readLine() != null){ 
        count++; 
        String str = br.readLine().toString().trim(); 
        s1 = str.substring(0, str.indexOf(",")); 
        s2 = str.substring(str.indexOf(",")+1,str.length()); 

        pstmt.setString(1, s1); 
        pstmt.setString(2, s2); 
        pstmt.addBatch(); 

        if(count%1000==0){ 
         pstmt.executeBatch(); 
         conn.commit(); 
         conn.close(); 
         conn = JDBCUtil.getConnection(); 
         conn.setAutoCommit(false); 
         pstmt = conn.prepareStatement(sql); 
        } 
        System.out.println("insert "+count+"line"); 
       } 
       if(count%1000!=0){ 
        pstmt.executeBatch(); 
        conn.commit(); 
       } 
       long end = System.currentTimeMillis(); 

       System.out.println("Total time spent:"+(end-start)); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      }finally{ 
       try { 
        pstmt.close(); 
        conn.close(); 
       } catch (SQLException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 
    } 

    //getConnection()//get jdbc Connection 
    public static Connection getConnection(){ 
    try { 
    Class.forName("com.mysql.jdbc.Driver"); 
    } catch (ClassNotFoundException e) { 
    e.printStackTrace(); 
    } 
    try { 
    conn = DriverManager.getConnection(url, userName, password); 
    } catch (SQLException e) { 
    e.printStackTrace(); 
    } 
    return conn; 
    } 

parlare per la prima volta, spero di poter fare a

Io sono la dimostrazione di cui sopra uso PreparedStatement [Leggi dati chiama un PreparedStatement una tantum inserire]

JDBC lotto ci sono 3 modi 1.use PreparedStatement demo:

try { 
     Class.forName("com.mysql.jdbc.Driver"); 
     conn = DriverManager.getConnection(o_url, userName, password); 
     conn.setAutoCommit(false); 
     String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id) VALUES(?,?,?,?,?)"; 
     PreparedStatement prest = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); 
     for(int x = 0; x < size; x++){ 
     prest.setString(1, "192.168.1.1"); 
     prest.setString(2, "localhost"); 
     prest.setString(3, "20081009"); 
     prest.setInt(4, 8); 
     prest.setString(5, "11111111"); 
     prest.addBatch(); 
     } 
     prest.executeBatch(); 
     conn.commit(); 
     conn.close(); 
} catch (SQLException ex) { 
    Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex); 
} 

2.use metodi Statement.addBatch demo:

uso
conn.setAutoCommit(false); 
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 
for(int x = 0; x < size; x++){ 
    stmt.addBatch("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')"); 
} 
stmt.executeBatch(); 
conn.commit(); 

3.Direct della dichiarazione demo:

conn.setAutoCommit(false); 
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
            ResultSet.CONCUR_READ_ONLY); 
for(int x = 0; x < size; x++){ 
    stmt.execute("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')"); 
} 
conn.commit(); 

Utilizzando il metodo di cui sopra Inserire i 100000 pezzi di tempo i dati che consumano: metodo 1: 17.844s metodo 2:18.421s metodo 3: 16.359s

+0

Questo codice sembra utile e pertinente alla domanda, ma ti suggerisco di modificare le righe sopra il codice. Non è chiaro cosa intendevi dire lì (demo1, demo2, ...) – Eran

+0

batch JDBC Esistono 2 modi – demo

+0

@demo: +1. Condividi anche, se hai qualche esperienza con MyBatis o Spring. –

2

Le versioni MS JDBC successive alla 4.1 hanno una classe SQLServerBulkCopy che presumo equivalente a una disponibile in .Net e, teoricamente, dovrebbe funzionare quanto l'utilità della riga di comando bcp. https://msdn.microsoft.com/en-us/library/mt221490%28v=sql.110%29.aspx

+0

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. – Marusyk

Problemi correlati