c# mysql 源代码下载_C#批量还原备份MySql--实战篇(源代码下载)

本文介绍了如何使用C#编程实现MySQL数据库的批量备份和还原操作,包括通过Process类调用cmd命令以及直接操作mysqldump.exe进程。通过改进的StartCmd方法支持执行多条命令,利用BackgroundWorker进行异步备份,确保用户体验。文章还讨论了线程安全和用户体验的优化策略。
摘要由CSDN通过智能技术生成

在C#批量还原备份MySql--cmd命令操作篇 我们了解了如何使用mysqldump.exe,mysql.exe命令来备份还原mysql,在这篇文章我们学习有C#来操作,并制作一个备份还原工具。

我们要操作cmd.exe使用到了Process类,使用这个类首先要引入命名空间System.Diagnostics,此类提供对本地和远程进程的访问并能够启动和停止本地系统进程。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

/// ///执行Cmd命令/// /// 要启动的进程的目录/// 要执行的命令 public static void StartCmd(String workingDirectory, String command)

{

Process p = new Process();

p.StartInfo.FileName = "cmd.exe";

p.StartInfo.WorkingDirectory = workingDirectory;

p.StartInfo.UseShellExecute = false;

p.StartInfo.RedirectStandardInput = true;

p.StartInfo.RedirectStandardOutput = true;

p.StartInfo.RedirectStandardError = true;

p.StartInfo.CreateNoWindow = true;

p.Start();

p.StandardInput.WriteLine(command);

p.StandardInput.WriteLine("exit");

p.WaitForExit();

p.Close();

}

在看看如何使用上方法:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

string appDircectroy="C:\\Program Files\\MySQL\\MySQL Server 5.5\\bin"

string cmd="mysqldump -hlocalhost -uroot -proot --default-character-set=utf8 --lock-tables --routines --force --quick Dbname>d:\backup.sql"

StartCmd(appDircectroy,cmd);

这里我们同Process操作cmd.exe,调用mysqldump.exe 执行命令"-hlocalhost  -uroot -proot --default-character-set=utf8 --lock-tables --routines --force  --quick Dbname>d:\backup.sql"备份数据库。其实我们也可以直接通过Process类直接调用mysqldump.exe进程执行命令,写法如下:

///

/// 使用mysqldump执行command命令

///

/// mysqldump.exe的目录

///

public static void StartMySqldump(string AppPath, string command)

{

ProcessStartInfo psi = new ProcessStartInfo(AppPath + @"\mysqldump.exe");

psi.Arguments = command;

psi.UseShellExecute = false; psi.RedirectStandardOutput = true;

psi.RedirectStandardInput = true;

psi.RedirectStandardError = true;

psi.CreateNoWindow = true;

Process pro = Process.Start(psi);

pro.WaitForExit();

pro.Close();

}

调用的方法和上面的使用基本一致,就是command命令不需要写mysqldump 改为"-hlocalhost  -uroot -proot --default-character-set=utf8 --lock-tables --routines --force  --quick Dbname>d:\backup.sql" 。

我再这里使用方法1,比较灵活方便,因为我们原因的使用也可以用到此方法执行mysql.exe还原命令,上篇中说到还原时,数据库如何不存在的使用,我们要先创建数据库,再还原,那么就是要执行两天命令,我们可以改一下方法1,使它可以执行多条命令,如下:

///

/// 执行Cmd命令

///

/// 要启动的进程的目录

/// 要执行的命令

public static void StartCmd(String workingDirectory, String[] commands)

{

Process p = new Process();

p.StartInfo.FileName = "cmd.exe";

p.StartInfo.WorkingDirectory = workingDirectory;

p.StartInfo.UseShellExecute = false;

p.StartInfo.RedirectStandardInput = true;

p.StartInfo.RedirectStandardOutput = true;

p.StartInfo.RedirectStandardError = true;

p.StartInfo.CreateNoWindow = true;

p.Start();

foreach (string cmd in commands)

{

p.StandardInput.WriteLine(cmd);

}

p.StandardInput.WriteLine("exit");

p.WaitForExit();

p.Close();

}

有了上面的函数,编写一个winform备份还原工具就比较容易实现了,但是现在我要备份300多个数据库,我要生成300多个数据库备份文件,当然我们也可以通过命令将300多个数据库,即所有数据库(包含mysql自带的系统库)备份到一个文件夹。还有一点要注意就是用户体验,假如备份的一个数据库很大,那么直接调用就会吧UI卡死,所以我们要用异步线程来解决此问题,我打算用四个线程同时执行备份,直到300多个数据库执行完毕。

有人可能对线程不熟悉,不用怕,其实.net提供了一个异步线程的封装 BackgroundWorker,用此类可以很简单实现。  我们用到BackgroundWorker提供的两个事件DoWork和RunWorkerCompleted,DoWork中写线程开始要执行的任务,RunWorkerCompleted中写线程执行的任务结束要执行的工作。看看简单的代码示例:

BackgroundWorker backgroundWorker = new BackgroundWorker();

backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);

backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);

backgroundWorker.RunWorkerAsync(remainDbNames); //remainDbName是list类型, 传入的参数,我保存要备份的库的名字,备份一个库就移除一个库

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)

{

List names = e.Argument as List; //获取传入的参数ramainDbName

BackupMany(filePath, names, boolBackdata); //执行备份方法

//e.Result = e.Argument.ToString();   //完成任务时向RunWorkerCompleted方法传递的结果参数

}

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

// writeText(textResult,true,"完成数据库"+e.Result.ToString()+"备份操作" + Environment.NewLine);

}

使用就是那么简单,下面看看我启用四个线程同时备份:

//只有在备份按钮事件中生成个异步线程即可

for (int i = 0; i < 4; i++)

{

BackgroundWorker backgroundWorker = new BackgroundWorker();

backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);

backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);

backgroundWorker.RunWorkerAsync(remainDbNames);

}

下面看看单个线程具体如何从remainDbName中取数据库的名字执行备份

object lockobject = new object(); //备份时的lock对象

delegate void WriteText(TextBox textbox, bool append, string text);

private void writeText(TextBox textbox, bool append, string msg)

{

if (this.InvokeRequired)

{

WriteText d = new WriteText(writeText);

object[] obj = new object[3];

obj[0] = textbox;

obj[1] = append;

obj[2] = msg;

this.Invoke(d, obj);

}

else

{

if (append)

textbox.AppendText(msg);

else

textbox.Text = msg;

}

}

private void BackupMany(string path, List dbNames, bool backupdata)

{

string name = null;

lock (lockobject)

{

if (dbNames.Count > 0)

{

name = dbNames[0];

dbNames.RemoveAt(0);

}

}

if (name != null)

{

Backup(path, name, backupdata);

BackupMany(path, dbNames, backupdata);

}

else

{

timer1.Enabled = false;

writeText(textResult, true, "全部执行完成!");

}

}

private void Backup(string path, string databaseName, bool backupdata)

{

try

{

writeText(textResult, true, DateTime.Now.ToString() + "开始数据库" + databaseName + "备份" + Environment.NewLine);

//String command = "mysqldump --quick --host=localhost --default-character-set=gb2312 --lock-tables --verbose --force --port=端口号 --user=用户名 --password=密码 数据库名 -r 备份到的地址";//构建执行的命令 String directory = path + "\\" + databaseName + ".sql";

String command;

if (backupdata)

{

command = string.Format("mysqldump --quick --host={1} --default-character-set={2} --lock-tables --routines --force --port={3} --user={4} --password={5} {6} -r \"{0}\"",

directory, host, characterSet, port, user, password, databaseName);

}

else

{

command = string.Format("mysqldump --quick --host={1} --default-character-set={2} -d --lock-tables --routines --force --port={3} --user={4} --password={5} {6} -r \"{0}\"",

directory, host, characterSet, port, user, password, databaseName);

}

Cmd.StartCmd(appDirecroty, command);

writeText(textResult, true, DateTime.Now.ToString() + @"数据库已成功备份到" + directory + "文件中" + Environment.NewLine);

counter++;

writeText(textBox1, false, "共" + totlecount + "个文件,已完成" + counter + "个文件");

}

catch (Exception ex)

{

writeText(txtErr, true, DateTime.Now.ToString() + "数据库" + databaseName + "备份失败!");

}

}

writeText是向TextBox写入文本的方法,因为副线程操作主线程生成的控件时,会有线程安全问题,所以要用异步委托。如何你知道这个怎么用,其实还有一个简单点的方法,就是把前程安全检查给关闭掉,在窗体onload中可以加入Control.CheckForIllegalCrossThreadCalls = false; 这句就可以跨线程操作UI而不会报错。

还原的实现和备份的操作差不多,这里就不提了。本想上传个一下代码可是找不到上传的方法。

刚刚学会怎么上传,这里是连接 源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值