venerdì 21 ottobre 2011

Java inserimenti batch con JDBC


In questo post vediamo come effettuare inserimenti massivi su una semplice tabella anagrafica, utilizzando JDBC sia in modalità normale che in modalità batch.

Per gestire la modalità "batch" bisogna:
  • Per ogni inserimento (o update) chiamare il metodo addBatch;
  • Alla fine della lista eseguire il metodo executeBatch();
La modalità batch è in genere più veloce.
Il Db Server utilizzato è MySql 5.5.
La ddl della tabella è la seguente:

CREATE TABLE  `test`.`persona` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `nome` varchar(45) DEFAULT NULL,
  `cognome` varchar(45) DEFAULT NULL,
  `data_nascita` date DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB


La documentazione dettagliata per l'utilizzo è disponibile qui
Questi sono i risultati che ottenuto per varie casisitiche:
  • 10 insert, modalità classica: 31 millisecondi modalità batch: 16 millisecondi;
  • 100 insert,modalità classica: 109 millisecondi modalità batch: 63 millisecondi;
  • 1000 insert, modalità classica: 703 millisecondi modalità batch: 609 millisecondi;
  • 10000 insert, modalità classica: 6203millisecondi modalità batch: 7359 millisecondi;
  • 100000 insert, modalità classica: 74485 millisecondi modalità batch: 73875 millisecondi
Di seguito incollo il codice della classe utilizzata:

package it.test;
import java.util.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
 class Elemento
{
    private String nome;
    private String cognome;
    private Date d;
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public String getCognome() {
        return cognome;
    }
    public void setCognome(String cognome) {
        this.cognome = cognome;
    }
    public Date getD() {
        return d;
    }
    public void setD(Date d) {
        this.d = d;
    }
   
    Elemento(String nome,String cognome,Date dataNascita){
        this.nome=nome;
        this.cognome=cognome;
        this.d=dataNascita;
    }
   
}
public class ModificheBatch {
    private Connection conn;
    private static final String INSERT="insert into test.persona(nome,cognome,data_nascita) values(?,?,?);";
    public ModificheBatch() throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        conn=DriverManager.getConnection(getUrlConnection());
    }
    private String getUrlConnection(){
        return "jdbc:mysql://localhost:3306/test?user=root&password=root";
    }
    private List<Elemento> generaListaPersone(int numero){
        List<Elemento> l=new ArrayList<Elemento>();
        for(int i=0;i<numero;i++){
            Elemento pers=new Elemento(generaNome(), generaCognome(), generaDataNascita());
            l.add(pers);
        }
        return l;
    }
    private String generaNome(){
        String[] nomi={"Mario","Paolo","Carlo","Gino","Pino"};
        //
        int rand=(int)Math.round(Math.random()*(nomi.length-1));
        return nomi[rand];
    }
    private String generaCognome(){
        String[] cognomi={"Rossi","Bianchi","Gialli","Verdi","Russo"};
        int rand=(int)Math.round(Math.random()*(cognomi.length-1));
        return cognomi[rand];
    }
    private Date generaDataNascita(){
        Date[] d={generaData(1, 1, 1978),generaData(20, 4, 1978),generaData(8, 7, 1987),generaData(15, 12, 1980),generaData(1, 4, 1970)};
        int rand=(int)Math.round(Math.random()*(d.length-1));
        return d[rand];
    }
    private Date generaData(int giorno,int mese,int anno){
        Calendar c=Calendar.getInstance();
        c.set(Calendar.YEAR, anno);
        c.set(Calendar.MONTH, mese-1);
        c.set(Calendar.DAY_OF_MONTH, giorno);
        return c.getTime();
    }
   
    public static void main(String[] args) throws Exception {
        ModificheBatch m=new ModificheBatch();
        int numeroInsert=100000;
        m.insertClassico(numeroInsert);
        m.insertBatch(numeroInsert);

    }
    public void insertClassico(int numeroInsert) throws Exception{
        System.out.println("******* INSERT CLASSICO *****");
        long time=System.currentTimeMillis();
        List<Elemento> lista=generaListaPersone(numeroInsert);
        PreparedStatement pst=conn.prepareStatement(INSERT);
        for(int i=0;i<lista.size();i++){
            Elemento el=lista.get(i);
            pst.setString(1, el.getNome());
            pst.setString(2, el.getCognome());
            pst.setDate(3, new java.sql.Date(el.getD().getTime()));
            pst.executeUpdate();
          
          
        }
        pst.close();
        long end=System.currentTimeMillis()-time;
        System.out.println("Millisecondi trascorsi "+ end);
        System.out.println("******* FINE INSERT CLASSICO *****");
    }
    public void insertBatch(int numeroInsert) throws Exception{
        System.out.println("******* INSERT BATCH *****");
        long time=System.currentTimeMillis();
        List<Elemento> lista=generaListaPersone(numeroInsert);
        PreparedStatement pst=conn.prepareStatement(INSERT);
        for(int i=0;i<lista.size();i++){
            Elemento el=lista.get(i);      
            pst.setString(1, el.getNome());
            pst.setString(2, el.getCognome());
            pst.setDate(3, new java.sql.Date(el.getD().getTime()));
            pst.addBatch();
          
        }
        pst.executeBatch();
        long end=System.currentTimeMillis()-time;
        System.out.println("Millisecondi trascorsi "+ end);
        System.out.println("******* FINE INSERT BATCH *****");
    }
}





Nessun commento:

Posta un commento