Quando si sviluppa un applicazione che permette di interagire e modificare un database può essere utile prevedere una funzione che permetta di effettuare velocemente e con un solo click il backup completo dell’intero database (dati, struttura, trigger e stored procedure).
Questa classe fa esattamente questo, e a differenza dei molti snippet che si trovano sul web è completa e autosufficente e documentata con javadoc, necessita soltanto della presenza nel sistema del comando “mysqldump” (presenza che viene verificata dalla classe stessa).
La classe avvia un istanza di mysqldump e permette di salvarne l’output in dei file di testo ,in un unico file zip o eventualmente in una stringa
A differenza della versione precedente ( descritta qui ) questa versione permette di importare/esportare anche tabelle che hanno vincoli di integrità relazionale.
Per fare questo disabilita il check delle Costraint , esegue l’intera importazione all’interno di una transazione, e poi le riattiva.
Questo comportamento può essere attivato con checkConstraint=false
Il comportamento di default è identico alla versione precedente
il file può essere scaricato da QUI
vediamo un esempio di utilizzo:
package cavia; import darshan.util.MysqlBackup; public class Main { public static void main(String[] args) { MysqlBackup b= new MysqlBackup("127.0.0.1", "3306", "root", "root", "darshan"); b.checkConstraint=false; b.all_to_zip("/home/darshan/Scrivania/post/dump.zip"); System.out.println("Done"); }
la classe viene istanziata con MysqlBackup(ip, porta, user, password, database) , poi con b.checkConstraint=false; disabilito il check delle costraint e con all_to_zip eseguo il dump in un file zip, per le altre funzioni affidatevi al javadoc che trovate anche qui
di seguito il sorgente
package darshan.util; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * * @author Vicenzo La Spesa * @version 2.0 * 14/06/2011 * http://www.thedarshan.com */ public class MysqlBackup { private static String head="SET AUTOCOMMIT=0; SET FOREIGN_KEY_CHECKS=0;\n"; private static String tail="SET FOREIGN_KEY_CHECKS=1;COMMIT;SET AUTOCOMMIT=1;\n"; /** * permette di abilitare/disabilitare il controllo dell'integrità referenziale * durante la fase di creazione, nel caso sia disabilitata è possibile inserire * tabelle che hanno riferimenti in qualsiasi ordine. */ public boolean checkConstraint=true; private String host, port, user,password, db; /** * boolean installed() * verifica se è possibile avviare mysqldump,<br> * La verifica viene effettuata avviando "mysqldump --help" e cercando la stringa * "mysqldump al suo interno" * @return true se il comando è disponibile, false altrimenti */ public boolean installed(){ try { Process run = Runtime.getRuntime().exec("mysqldump --help"); InputStream in = run.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String out = br.readLine(); int n=out.indexOf("mysqldump"); br.close(); in.close(); if(n >-1 && n<2) return true; } catch (IOException ex) { Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex); } return false; } /** * @param host * @param port * @param user * @param password * @param db * @return una stringa con il backup del database, <br> una stringa vuota se scrive sullo stream * @throws java.lang.Exception * * esegue il backup dei dati su stringa,o su uno stream dato come argomento <br> * è un overload */ private String getData(String host, String port, String user, String password, String db) throws Exception{ return getData(host, port, user, password, db,null); } private String getData(String host, String port, String user, String password, String db, OutputStream stream) throws Exception { Process run = Runtime.getRuntime().exec( "mysqldump --host=" + host + " --port=" + port + " --user=" + user + " --password=" + password + " --compact --complete-insert --extended-insert " + "--skip-comments --skip-triggers " + db); InputStream in = run.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); StringBuilder temp = new StringBuilder(); DataOutputStream output=new DataOutputStream(stream); String buffer; if(!checkConstraint)output.writeBytes(head); while ((buffer = br.readLine()) != null) { if(stream!=null){ output.writeBytes(buffer+"\n"); }else{ temp.append(buffer).append("\n"); } } if(!checkConstraint)output.writeBytes(tail); br.close(); in.close(); return temp.toString();//se scrive sullo stream è una stringa vuota } /** * * @param host * @param port * @param user * @param password * @param db * @return una stringa con la struttura del db * @throws java.lang.Exception * * estrae la struttura del db e le stored procedure */ static private String getRoutine(String host, String port, String user, String password, String db) throws Exception { Process run = Runtime.getRuntime().exec( "mysqldump --host=" + host + " --port=" + port + " --user=" + user + " --password=" + password + " --compact --no-create-info " + "--no-data --routines " + db); InputStream in = run.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); StringBuilder temp = new StringBuilder(); String buffer; while ((buffer = br.readLine()) != null) { temp.append(buffer).append("\n"); } br.close(); in.close(); return temp.toString(); } public MysqlBackup(String host, String port, String user, String password, String db) { this.host=host; this.port=port; this.user=user; this.password=password; this.db=db; } /** * @throws java.lang.Exception * * Wrapper di getData * <strong> * LA FUNZIONE NON È OTTIMIZZATA E ALLOCA MOLTA RAM <BR> * SERVE SOLO PER FARE TEST * </strong> */ public String data_to_string() throws Exception{ return getData(host, port, user, password, db); } /** * * Wrapper di getRoutine() * @throws java.lang.Exception */ public String routine_to_string() throws Exception{ return getRoutine(host, port, user, password, db); } /** * * @param nomefile * @return true se va bene, false altrimenti * Scrive i dati su un file, funzione ottimizzata per allocare meno ram */ public boolean data_to_file(String nomefile) { File filedst = new File(nomefile); try { FileOutputStream dest = new FileOutputStream(filedst); getData(host, port, user, password, db, dest); dest.flush(); dest.close(); } catch (Exception ex) { Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex); return false; } return true; } /** * * @param nomefile * @return true se va bene, false altrimenti * Scrive i dati su un file */ public boolean routine_to_file(String nomefile){ File filedst = new File(nomefile); try { FileOutputStream dest = new FileOutputStream(filedst); dest.write(routine_to_string().getBytes()); dest.flush(); dest.close(); } catch (Exception ex) { Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex); return false; } return true; } /** * * @param nomefile * @return true se va bene, false altrimenti * genera un file zip con all'interno due files: <br> * data.sql con i dati <br> * routine.sql con la struttura e le procedure */ public boolean all_to_zip(String nomefile){ try { File filedst = new File(nomefile); FileOutputStream dest = new FileOutputStream(filedst); ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(dest)); zip.setMethod(ZipOutputStream.DEFLATED); zip.setLevel(Deflater.BEST_COMPRESSION); zip.putNextEntry(new ZipEntry("data.sql")); getData(host, port, user, password, db, zip); zip.putNextEntry(new ZipEntry("routine.sql")); zip.write(routine_to_string().getBytes()); zip.close(); dest.close(); } catch (Exception ex) { Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex); return false; } return true; } }
5 comments
Vai al modulo dei commenti ↓
Antonio
3 novembre 2011 a 18:47 (UTC 2) Link a questo commento
Ciao Vincenzo, sto provando ad utilizzare la tua classe, ma avendo un Mac non riesco a trovare il programma mysqldump.exe hai idea di come posso aggirare la cosa?
Vincenzo La Spesa
7 novembre 2011 a 15:20 (UTC 2) Link a questo commento
mmm, non ho mai toccato un Mac per più di 10 minuti di fila… provo a chiedere ai miei contatti xD
Vincenzo La Spesa
10 novembre 2011 a 03:01 (UTC 2) Link a questo commento
Dunque, intanto non devi cercare mysqldump.exe ma semplicemente mysqldump, se lo chiami da terminale lo trova? o non l’hai proprio installato? se è installato basta un which mysqldump per sapere dove si trova
Remo
1 marzo 2013 a 20:56 (UTC 2) Link a questo commento
Scusami ma c’è una classe che fa anche il ripristino da file dump.zip ?
Vincenzo La Spesa
12 marzo 2013 a 23:09 (UTC 2) Link a questo commento
non so.
purtroppo il mio codice però non lo fa, l’ho sviluppato per fare backup periodici nella speranza che non servissero mai xD