How to backup a mysql database from a java code such that:
It's saving path is dynamically allocated.
Spaces in Path do not create problems.
Path is generated using the executing jar file.
DBname,DBusername or DBpass are dynamically allotted.
Creating a specialized folder to save the backup file.
Note: The codes given below are one way of solving the problem and probably not the best method. Everything is changeable inside the code. If you do not have mysql in environment variables, add the path before mysqldump and mysql (e.g. For XAMPP, C:\xampp\mysql\bin\mysqldump)
(Hope, this will solve your problems. Took me a day to completely figure out everything and implement them properly)
Method for Backup:
public static void Backupdbtosql() {
try {
/*NOTE: Getting path to the Jar file being executed*/
/*NOTE: YourImplementingClass-> replace with the class executing the code*/
CodeSource codeSource = YourImplementingClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
/*NOTE: Creating Database Constraints*/
String dbName = "YourDBName";
String dbUser = "YourUserName";
String dbPass = "YourUserPassword";
/*NOTE: Creating Path Constraints for folder saving*/
/*NOTE: Here the backup folder is created for saving inside it*/
String folderPath = jarDir + "\\backup";
/*NOTE: Creating Folder if it does not exist*/
File f1 = new File(folderPath);
f1.mkdir();
/*NOTE: Creating Path Constraints for backup saving*/
/*NOTE: Here the backup is saved in a folder called backup with the name backup.sql*/
String savePath = "\"" + jarDir + "\\backup\\" + "backup.sql\"";
/*NOTE: Used to create a cmd command*/
String executeCmd = "mysqldump -u" + dbUser + " -p" + dbPass + " --database " + dbName + " -r " + savePath;
/*NOTE: Executing the command here*/
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
/*NOTE: processComplete=0 if correctly executed, will contain other values if not*/
if (processComplete == 0) {
System.out.println("Backup Complete");
} else {
System.out.println("Backup Failure");
}
} catch (URISyntaxException | IOException | InterruptedException ex) {
JOptionPane.showMessageDialog(null, "Error at Backuprestore" + ex.getMessage());
}
}
Method for Restore:
public static void Restoredbfromsql(String s) {
try {
/*NOTE: String s is the mysql file name including the .sql in its name*/
/*NOTE: Getting path to the Jar file being executed*/
/*NOTE: YourImplementingClass-> replace with the class executing the code*/
CodeSource codeSource = YourImplementingClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
/*NOTE: Creating Database Constraints*/
String dbName = "YourDBName";
String dbUser = "YourUserName";
String dbPass = "YourUserPassword";
/*NOTE: Creating Path Constraints for restoring*/
String restorePath = jarDir + "\\backup" + "\\" + s;
/*NOTE: Used to create a cmd command*/
/*NOTE: Do not create a single large string, this will cause buffer locking, use string array*/
String[] executeCmd = new String[]{"mysql", dbName, "-u" + dbUser, "-p" + dbPass, "-e", " source " + restorePath};
/*NOTE: processComplete=0 if correctly executed, will contain other values if not*/
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
/*NOTE: processComplete=0 if correctly executed, will contain other values if not*/
if (processComplete == 0) {
JOptionPane.showMessageDialog(null, "Successfully restored from SQL : " + s);
} else {
JOptionPane.showMessageDialog(null, "Error at restoring");
}
} catch (URISyntaxException | IOException | InterruptedException | HeadlessException ex) {
JOptionPane.showMessageDialog(null, "Error at Restoredbfromsql" + ex.getMessage());
}
}
If Hibernate is configured properly, this is cake:
Session session = HibernateUtil.getSessionFactory().openSession();
// for every table, have the bean implement Serializable and use the next 4 lines
List <TblBean> tblCollection = session.createCriteria(TblBean.class).list();
FileOutputStream backup = new FileOutputStream("backupOf"+TblBean.getClass().getName()+".dat");
ObjectOutputStream backupWriter = new ObjectOutputStream(backup);
backupWriter.write(tblCollection);
public static String getData(String host, String port, String user, String password, String db,String table) throws Exception {
//an "C:/xampp/mysql/bin/mysqldump" ---- location ito han mysqldump
Process run = Runtime.getRuntime().exec(
"C:/xampp/mysql/bin/mysqldump --host=" + host + " --port=" + port +
" --user=" + user + " --password=" + password +
" --compact --databases --add-drop-table --complete-insert --extended-insert " +
"--skip-comments --skip-triggers "+ db+" --tables "+table);
InputStream in = run.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuffer temp = new StringBuffer();
int count;
char[] cbuf = new char[BUFFER];
while ((count = br.read(cbuf, 0, BUFFER)) != -1)
temp.append(cbuf, 0, count);
br.close();
in.close();
return temp.toString();
}
In addition to chettyharish's answer, if your server os is ubuntu the path should have front slash '/' instead of backslash '\' such as /path/to/your/file
For example: String savePath = "\"" + jarDir + "\\backup\\" + "backup.sql\"";
Will be : String savePath="/"+jarDir+"/backup/backup.sql"
Related
I try to use SQL*Loader import data to Oracle. The concrete method is that I make a Java class to call "sqlldr". There is a excerpt of my method as follows:
public class SqlldrImportDataFile {
public String executeImport(String user, String password, String database,String fileRoute, String ctlfileName,
String logsRoute,String logfileName) {
InputStream ins = null;
String dos = "sqlldr " + user + "/" + password + "#" + database + " control=" + fileRoute + ctlfileName + " log=" + logsRoute + logfileName;
String returnCode = "0";
try {
Process process = Runtime.getRuntime().exec(dos);
ins = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
String line = null;
while ((line = reader.readLine()) != null) {
String msg = new String(line.getBytes("ISO-8859-1"), "UTF-8");
}
int exitValue = process.waitFor();
process.getOutputStream().close();
reader.close();
ins.close();
} catch (Exception e) {
return "-1";
}
return returnCode;
}
}
Howerver,there is a problem when I run application which is "java.io.IOException: Cannot run program "sqlldr": error=2, A file or directory in the path name does not exist." The detail error information as follows:
java.io.IOException: Cannot run program "sqlldr": error=2, A file or directory in the path name does not exist.
at java.lang.ProcessBuilder.processException(ProcessBuilder.java:489)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:468)
at java.lang.Runtime.exec(Runtime.java:604)
at java.lang.Runtime.exec(Runtime.java:442)
at java.lang.Runtime.exec(Runtime.java:339)
at com.sdb.bbcp.common.SqlldrImportDataFile.executeImport(SqlldrImportDataFile.java:188)
at com.sdb.bbcp.common.SqlldrImportDataFile.execute(SqlldrImportDataFile.java:80)
at com.sdb.common.flow.SDBEMPFlow.execute(SDBEMPFlow.java:175)
at com.ecc.emp.flow.Operation.execute(Operation.java:96)
at com.ecc.emp.flow.EMPBusinessLogic.execute(EMPBusinessLogic.java:89)
at com.ecc.emp.processor.EMPBusinessLogicCaller.execute(EMPBusinessLogicCaller.java:112)
at com.sdb.common.flow.SDBEMPFlow.execute(SDBEMPFlow.java:175)
at com.ecc.emp.flow.Operation.execute(Operation.java:96)
at com.ecc.emp.flow.EMPBusinessLogic.execute(EMPBusinessLogic.java:89)
at com.ecc.emp.processor.EMPBusinessLogicCaller.execute(EMPBusinessLogicCaller.java:112)
at com.sdb.common.flow.SDBEMPFlow.execute(SDBEMPFlow.java:175)
at com.ecc.emp.flow.Operation.execute(Operation.java:96)
at com.ecc.emp.flow.EMPBusinessLogic.execute(EMPBusinessLogic.java:89)
at com.sdb.bbcp.communication.BBCPTCPIPRequestService.handleRequest(BBCPTCPIPRequestService.java:190)
at com.sdb.bbcp.communication.BBCPTCPIPServiceServlet.processNewPackage(BBCPTCPIPServiceServlet.java:505)
at com.ecc.emp.tcpip.TCPIPService.processNewPackage(TCPIPService.java:652)
at com.ecc.emp.tcpip.TCPIPService.newPackageReceived(TCPIPService.java:567)
at com.ecc.emp.tcpip.SocketProcessThread.runTask(SocketProcessThread.java:127)
at com.ecc.emp.tcpip.SocketProcessThread.run(SocketProcessThread.java:107)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
at java.lang.Thread.run(Thread.java:784)
I search too much resoures from Internet.And I check environment of server,execute command by writting "sqlldr" to shell...But it until error.
User: username
Server: AIX 7.1.0.0
$ORACLE_HOME=/oracle/../product/10.2.0
$PATH=.:$ORACLE_HOME/bin:.
chown -R username /oracle/
User Groups: staff system dba
So what should I do?
P.S. The applicaton work normally on our other machines.
I have a simple program that reads in commands and performs them. Rightnow I have this code for inserting certain text into a text file:
Example command:
INSERT "John Smith" INTO college.student
My main method:
else if(command.substring(0,6).equalsIgnoreCase("INSERT")){
String string = command.substring(7, command.indexOf("INTO") - 1);
String DBNameTBName = command.substring(command.indexOf("INTO") + 5);
String tableName = DBNameTBName.substring(DBNameTBName.indexOf(".") + 1);
String DBName = DBNameTBName.substring(0, DBNameTBName.indexOf("."));
if(DBCommands.insert(string, DBName, tableName)){
statfileWriter.println("Inserted " + string + " into table " + tableName + " in " + DBName);
statfileWriter.println("(" + command + ")");
statfileWriter.flush();
}
else{
errfileWriter.println("Error: Could not insert " + string + " into table " + tableName + " in " + DBName);
errfileWriter.println("(" + command + ")");
errfileWriter.flush();
}
And the insert method it calls:
public static boolean insert(String string, String DBName, String tableName){
try{
string = string.substring(string.indexOf('"') + 1, string.lastIndexOf('"')); //removes quotes
File tableToWriteTo = new File(DBName + "/" + tableName + ".txt");
if (!tableToWriteTo.exists()){
return false;
}
PrintWriter writer = new PrintWriter(new FileWriter
(tableToWriteTo, true));
writer.println(string);
writer.close();
return true;
}
catch(Exception e){
return false;
}
}
I am getting very weird behavior with my insert method. It returns true as it always prints to my status log and not error log. I know the method to create the .txt file is working perfectly, I have tested it many times and the student.txt file is always there. With my insert command, if I change the File = new File line to this:
File tableToWriteTo = new File(tableName + ".txt");
Then it unsurprisingly creates a .txt file called "student" with my example command, but not in the "DBName" folder. If I change it to this:
File tableToWriteTo = new File(DBName + "/" + tableName);
Then it creates a file called "student" with no type (as in, Windows asks what I want to open it with) but puts in the string I want to insert into it. I should note that if there are multiple INSERT commands then it writes all the strings as I would like it to.
I have tried declaring PrintWriter and File in my main method and passing them in, but that doesn't work either.
How can I get it to write into students.txt in the directory college?
EDIT: Oh my goodness, I'm the stupidest person on Earth. I didn't look at the full commands list I received for this assignment and I forgot there was a delete command and they were BOTH working. I would delete this question but I'll leave this up in case anyone in the future wants to see an example of FileWriter.
I changed the if condition in the insert method. The file is not expected to exist. So ideally the condition should not be negated. I used the following code and it is working for me.
public class InsertToWriteTo {
public static void main(String[] args) {
boolean ret = insert("\"hello\"", "college", "student");
System.out.println(ret);
}
public static boolean insert(String string, String DBName, String tableName) {
try {
string = string.substring(string.indexOf('"') + 1, string.lastIndexOf('"')); // removes quotes
File tableToWriteTo = new File(DBName + "/" + tableName + ".txt");
if (tableToWriteTo.exists()) { // changed condition
System.out.println("File exists");
return false;
}
PrintWriter writer = new PrintWriter(new FileWriter(tableToWriteTo, true));
writer.println(string);
writer.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
Hope this helps!
Something is going wrong with my program for database recovery, this error hides my happiness:
java.io.IOException: Cannot run program "mysql":CreateProcess error=2,
The system cannot find the file specified
file to be recovered is located in D:/Backup/backup.sql when I browse and open the file from this path then error appears when I click recovery button. Please help me solve this problem.
below is my code with JFileChooser for browsing file location.
browseButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
String recPath = "";
JFileChooser fc = null;
if (fc == null) {
fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fc.setAcceptAllFileFilterUsed(false);
}
int returnVal = fc.showDialog(null, "Open");
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
recPath = file.getAbsolutePath();
sourceField.setText(recPath);
}
}
}
);
recoveryButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
try{
String databaseName ="jdbc:mysql://localhost:3306/myDB";
String userName ="abc";
String password ="123";
String source = sourceField.getText();
int processComplete;
String[] executeCmd = new String[]{"mysql",databaseName, "--user=" + userName, "--password=" + password, "-e", "source"+source};
//sava the command in a array
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);// execute the command
processComplete = runtimeProcess.waitFor();// get the result to variable
if(processComplete==1){
JOptionPane.showMessageDialog(null, "Restore Failed");
}
else if(processComplete==0){
JOptionPane.showMessageDialog(null, "Restore Completed");
}
}
catch(Exception ex){
JOptionPane.showMessageDialog(null,ex);
}
}
}
);
You should add path to 'mysql' into 'Path' variables or specify full path in your code:
Try
String[] executeCmd = new String[]{"\FULL PATH HERE\mysql",databaseName, "--user=" + userName, "--password=" + password, "-e", "source"+source};
instead of
String[] executeCmd = new String[]{"mysql",databaseName, "--user=" + userName, "--password=" + password, "-e", "source"+source};
This answer is correct in 2018/06/07...
String[] executeCmd = new String[]{"\FULL PATH HERE\mysql",databaseName, "--user=" + userName, "--password=" + password, "-e", "source"+source};
A example will be :
String[] restoreCmd = new String[] { "C:\\Program Files\\MySQL\\MySQL Server 5.7\\bin\\mysql ", bd,"--user=" + usuario, "--password=" + password, "-e", "source " + pathToFile }
You can add "\FULL PATH To MySQL"
eg : "C:\Program Files\MySQL\MySQL Server 5.7\bin"
to the environment path variables
I was trying to execute the mysql command using java but this always keeps giving error.
String dbName = "dth";
String dbUser = "root";
String dbPass = "root";
String executeCmd = "";
executeCmd = "mysqldump -u " + dbUser + " -p" + dbPass + " " + dbName + " -r C:\\backup.sql";
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) {
System.out.println("Backup taken successfully");
} else {
System.out.println("Could not take mysql backup");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
I tried the above code but I couldn't get it done, keeps giving me
CreateProcess error=2, The system cannot find the file specified
error.
I have tried it by creating a .sql file on the location and still I get the same error.
Add the directory in which mysqldump resides into your path environment variable or use the full pathname I.e c:\directory\mysqldump
I want to export my MySQL database using my java code. But I have not found any way to do. What I want to do that there is a button in my app as "Export Database". When that button is clicked, my database should be exported to specified path. I have used the following code but it does'nt worked :
Runtime runtime = Runtime.getRuntime();
runtime.exec("C:\\Program Files\\MySql\\MySql Server 5.5\\bin\\mysqldump -u root -p myDatabase> D:\\backup.sql");
How should I do this task. Thanks.
Two problems :
the space between -p and the password
the space inside the path to the executable
Prefer this :
runtime.exec(new String[]{"C:\\Program Files\\MySql\\MySql Server 5.5\\bin\\mysqldump", "-u", "root", "-pmyDatabase" "> D:\\backup.sql"});
Note that if you have a problem with runtime.exec, you should look at the streams you can get from the returned Process. Not looking at those streams in case of error is a little like not looking at the exception when one is thrown.
Backup:
/******************************************************/
//Database Properties
/******************************************************/
String dbName = “dbName”;
String dbUser = “dbUser”;
String dbPass = “dbPass”;
/***********************************************************/
// Execute Shell Command
/***********************************************************/
String executeCmd = “”;
executeCmd = “mysqldump -u “+dbUser+” -p”+dbPass+” “+dbName+” -r backup.sql”;
}
Process runtimeProcess =Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
if(processComplete == 0){
out.println(“Backup taken successfully”);
} else {
out.println(“Could not take mysql backup”);
}
Restore:
/******************************************************/
//Database Properties
/******************************************************/
String dbName = “dbName”;
String dbUser = “dbUser”;
String dbPass = “dbPass”;
/***********************************************************/
// Execute Shell Command
/***********************************************************/
String executeCmd = “”;
executeCmd = new String[]{“/bin/sh”, “-c”, “mysql -u” + dbUser+ ” -p”+dbPass+” ” + dbName+ ” < backup.sql” };
}
Process runtimeProcess =Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
if(processComplete == 0){
out.println(“success”);
} else {
out.println(“restore failure”);
}
You can try this.
public void actionPerformed(ActionEvent evt)
{
private String m_MySqlPath="";
ResultSet res=null;
res = DBHandler.getInstance().executeQuery("select ##basedir",null);
while(res.next())
{
m_MySqlPath=res.getString(1) ;
}
m_MySqlPath = m_MySqlPath.replace("\\Data\\", "\\bin\\");
if (exportDB.isSelected()
{
try {
String executeCmd = m_MySqlPath + "\\mysqldump -u " + DB_USER
+" -p" + DB_PASSWORD + " " + DB_NAME + " -r " + "\""+FilePath + "\\"
+ FileName+"\"";
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd, null);
BufferedReader r=new BufferedReader(new InputStreamReader(runtimeProcess.getInputStream()));
String s;
while((s=r.readLine())!=null)
{
System.out.println(s);
}
return true;
}
catch (final Exception ex) {
ex.printstackTrace();
return false;
}
}