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 autosufficiente 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
Spero solo che questo codice non finisca schiaffato in qualche forum che non linka nemmeno il sito, fosse per me estenderei il 41bis ai succhiatori di codice
ecco il link per il download [MysqlBackup.java] Questa versione è obsoleta, fare riferimento alla versione descritta QUI
di seguito il sorgente
package gestoredb; 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 * http://thedarshan.wordpress.com * "Il backup è quella cosa totalmente inutile finché non serve" */ public class MysqlBackup { private String host, port, user,password, db; /** * boolean installed() * verifica se è possibile avviare mysqldump, * 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)); StringBuffer temp = new StringBuffer(); 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, 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 * è un overload */ static private String getData(String host, String port, String user, String password, String db) throws Exception{ return getData(host, port, user, password, db,null); } static 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)); StringBuffer temp = new StringBuffer(); DataOutputStream output=new DataOutputStream(stream); String buffer; while ((buffer = br.readLine()) != null) { if(stream!=null){ output.writeBytes(buffer+"\n"); }else{ temp.append(buffer+"\n"); } } 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)); StringBuffer temp = new StringBuffer(); String buffer; while ((buffer = br.readLine()) != null) { temp.append(buffer+"\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 * 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: * data.sql con i dati * 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; } }
8 comments
Vai al modulo dei commenti ↓
ADriano
8 luglio 2009 a 13:50 (UTC 2) Link a questo commento
E se invece di un file zip volessi avere solo il file data.sql?
Cosa dovrei modificare?
thedarshan
8 luglio 2009 a 22:40 (UTC 2) Link a questo commento
non devi modificare nulla, devi usare la funzione data_to_file(String nomefile).
includi l’intera classe nel progetto e usi le funzioni che ti servono
melmar
3 ottobre 2009 a 14:14 (UTC 2) Link a questo commento
ho provato ad utilizzare la tua classe, ma sempre la stessa eccezione : “Cannot run program “mysqldump””
thedarshan
3 ottobre 2009 a 17:22 (UTC 2) Link a questo commento
assicurati che mysqldump sia installato e sia nel path.
di solito viene installato insieme al server
melmar
13 ottobre 2009 a 12:55 (UTC 2) Link a questo commento
è installato, adesso mi hai fatto venire alcuni dubbi sul path. In che cartella dovrebbe essere?
thedarshan
13 ottobre 2009 a 14:51 (UTC 2) Link a questo commento
deve essere o nella directory corrente o in una delle directory specificate nella variabile d’ambiente path.
per visualizzare la variabile path da una shell di dos puoi usare “SET PATH”
per modificarla da terminale francamente non lo so, windows xp e superiori non usano il file autoexec.bat o autoexec.nt
ti consiglio di cliccare col sinistro su risorse del computer e poi fare
Proprietà
Avanzate
Variabili d’ambiente
si trova tra le variabili di sistema
giuseppe
24 aprile 2010 a 22:38 (UTC 2) Link a questo commento
ciao ho provato ad usare la tua classe, ma ho notato che quando creo il file zip, l’annesso file .sql non contiene solo i dati (ovvero solo le istruzioni INSERT) ma l’intera struttura del db.
Ora la domanda è :
è possibile creare solo uno script senza la struttura del db??
Grazie mille e complimenti
thedarshan
26 aprile 2010 a 13:59 (UTC 2) Link a questo commento
dovrebbe essere possibile aggiungendo i flag
“–no-create-db –no-create-info” alla riga 74
http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html