21.2 C#操作MySQL数据库
连接MySQL数据库之后,通过MySqlCommand对象来获取SQL语句。然后,通过ExecuteNonQuery()方法对数据库进行插入、更新和删除等操作;通过ExecuteNonQuery()方法查询数据库中的数据,也可以通过ExecuteScalar()方法查询数据;通过MySqlDataReader对象获取SELECT语句的查询结果。除了上述方法操作数据库以外,还可以使用 MySQLDataAdapter对象、DataSet对象、DataTable对象来操作MySQL数据库。本节将详细向读者介绍C#操作MySQL数据库的方法。
21.2.1 创建 MySqlCommand对象
MySqlCommand对象主要用来管理MySqlConnector对象和SQL语句。MySqlCommand对象的创建方法如下:
MySqlCommand com = new MySqlCommand("SQL语句",conn);
其中,“SQL语句”可以是INSERT语句、UPDATE语句、DELETE语句和SELECT 语句等;conn为MySqlConnector对象。C#中也可以使用下面的方式来创建MySqlCommand对象。语句如下:
MySqlCommand com = new MySqlCommand(); com.Connection=conn; com.CommandText="SQL语句";
这种方式可以按照需要为MySqlCommand对象添加不同的sql语句。
技巧:如果需要使用一个MySqlCommand对象执行sql语句时,这种方法很有效。例如,用户可以通过com.CommandText获取一个SELECT语句。SELECT语句执行完后,用户可以再通过com.CommandText获取一个UPDATE语句、DELETE 语句等。
21.2.2插入、更新或者删除数据
如果需要对MySQL数据库执行插入、更新和删除等操作,那么需要MySqlCommand对象调用ExecuteNonQuery()方法来实现。ExecuteNonQuery()方法返回一个整型的数字。下面是调用ExecuteNonQuery()方法的代码。
int i = com.ExecuteNonQuery();
其中,com为MySqlCommand对象。com通过ExecuteNonQuery()方法执行com中的INSERT语句、UPDATE语句和DELETE语句等。ExecuteNonQuery()方法执行完后,返回影响表的行数。
【示例21-2】下面通过ExecuteNonQuery()方法执行一个INSERT语句。这个INSERT语句向score表中插入两条记录,其部分代码如下:
MySqlCommand com = new MySqlCommand(); //创建 MySqlCommand 对象 com.Connection = conn; //将 conn 赋值给 com 的 Connection 属性 //com对象通过CommandText获取INSERT语句 com.CommandText = "INSERT INTO score VALUES(21, 902,'英语' 85), (22,903,'英语',90)"; int i=com.ExecuteNonQuery(); //执行INSERT语句,返回插入的记录数 if(i>0) //判断是否插入成功,输出插入的记录数 { Console.WriteLine("插入的记录数为:"+1); }
如果INSERT执行成功,控制台会输出“插入的记录数为:2”的信息。这表示一次插入了两条记录。
ExecuteNonQuery()方法可以一次执行多条SQL语句,返回值是所有SQL语句影响表的行数的总和。
【示例21-3】下面通过ExecuteNonQuery()方法执行一个UPDATE语句和一个DELETE语句。其部分代码如下:
MySqlCommand com = new MySqlCommand(); com.Connection = conn; //com对象通过CommandText获取UPDATE语句 com.CommandText = "UPDATE score SET gradeWHERE id=6"; int i=com.ExecuteNonQuery(); if (i > 0) { Console.WiteLine("更新和删除的总记录数为:"+丨); }
UPDATE语句和DELETE语句直接用分号(;)隔开。UPDATE语句和DELETE语句执行成功后,控制台会输出“更新和删除的总记录数为:2”。因为,UPDATE语句更新了一条记录,DELETE语句删除了一条记录;所以,ExecuteNonQuery()方法的返回值为2。
21.2.3 使用SELECT语句查询数据
ExecuteNonQuery()方法不能执行SELECT语句。如果需要执行SELECT语句,则需要MySqlCommand对象调用ExecuteReader()方法来实现。ExecuteReader()方法返回一个MySqlDataReaded对象。调用ExecuteReader()方法的代码如下:
MySqlDataReader dr=com.ExecuteReader();
其中,dr是一个MySqlDataReader对象。ExecuteReader()方法查询出来的记录都存储在dr中。通过dr调用Read()方法读取数据。如果读取到记录,Read()函数返回true。如果没有读取到记录,Read(函数返回false。读取记录后,通过dr["ColumnName"]或者dr[n]来读取相应字段的数据。
【示例21-4】下面通过ExecuteReader()方法执行一个SELECT语句。其部分代码如下:
MySqlCommand com = null; //创建 MySqlCjommand 对象 MySqlDataReader dr = null; //创建 MySqldataReader 对象 com = new MySqlCommand("SELECT * FROM score",conn); //将 MySqlCommand 对象实例化 dr = com.ExecuteReader(); //调用ExecuteReader()()方法执行 SELECT 语句 while (dr.Read()) //调用尺Read()函数读取查询结果的记录 { Console.WriteLine(dr["id"] + " " + dr["stu_id"] + " "+ dr["c_name"]+" " + dr["grade"]); }
com调用ExecuteReader()方法来执行SELECT语句,执行结果返回给dr,dr调用Read()函数读取数据,如果Read()返回值为TRUE,执行while循环。在while循环中读取每条记录的值。ds["id"]表示读取id字段的值,后面的依次类推。Console.WriteLine()方法可以将读取的结果输出到控制台。所有记录读取完毕后或者读取时遇到错误,Read()方法返回false,while循环结朿。
21.2.4 一次执行多个SELECT语句
一次执行多个SELECT语句时,ExecuteReader()方法会将所有SELECT语句的执行结果都返回给MySqlDataReader对象。但是MySqlDataReader对象一次只能读取一个SELECT语句的查询结果。如果需要读取下一个SELECT的执行结果,MySqlDataReader对象需要调用NextResult().NextResult()方法获取到下一个SELECT语句的查询结果时,该方法返回true。然后MySqlDataReader对象可以通过Read()函数来读取数据。如果NextResult()返回值为false,那说明所有结果已经全都读取出来了。
注意:一次执行多个SELECT语句时,一定不要忘记使用ExecuteReader()函数获取下一个 NextResult()语句的查询结果。如果不使用NextResult()函数,MySqlDataReader对象 只能取得第一个SELECT语句的查询结果。最好将NextResult()函数与while循环一起使用。
【示例21-5】下面通过ExecuteReader()方法执行两个SELECT语句。其部分代码如下:
MySqlCommand com = null; //创建 MySqlCommand 对象 MySqlDataReader dr = null; //创建 MySqlDataReader 对象 //将com实例化,然后将两个SELECT语句传递给com com = new MySqlCommand("SELECT * FROM score; SELECT * FROM Studenf,conn); dr = com.ExecuteReader(); //调用ExecuteReader()方法执行 SELECT 语句 while (dr.Read()) //调用?Read()函数读取查询结果的记录 { Console.WriteLine(dr["id"] + " " + dr["stu_id"] + " " + dr["c_name"]+" "+dr["grade"]); if(dr.NextResult()){ //调用NextResult()方法获取下一个查询结果 while (dr.Read()){ Console.WriteLine(dr["id"] + " " + dr["name"] + " " + dr["address"]+" "+dr["department"]); } }
其中,dr为MySqlDataReader对象。上面两个SELECT语句的查询结果都存储在dr中。但是dr.Read()只能获取第一个SELECT语句的查询结果。如果要获取第二个SELECT语句的查询结果,必须执行dr.NextResult()。当dr.NextResult()返回值为true时,dr调用 Read()函数来读取第二个SELECT语句的查询结果。
21.2.5 处理SELECT语句只返回一个值的情况
如果SELECT语句只返回一个值,可以使用ExecuteScalar()方法来执行SELECT语句。 因为,ExecuteScalar()方法所使用的资源比ExecuteReader()方法少。
说明:ExecuteScalar()方法返回一个object对象,而不是MySqlDataReader对象。因此, 使用 ExecuteScalar()方法时不需要创建 MySqlDataReader 对象。MySqlDataReader对象占用的资源比较多,而且不会自动释放。所以,对于只有一个查询结果的查 询语句可以考虑使用ExecuteScalar()方法来执行。C#可以直接通过类型转换的方法将ExecuteScalar()方法返回的object对象转换为需要的类型。
【示例21-6】下面通过ExecuteScalar()方法查询当前的系统时间。其部分代码如下:
MySqlCommand com = null; //创建 MySqlCommand 对象 com = new MySqlCommand("SELECT NOW()", conn); //实例化 MySqlCommand 对象, DateTime dt = (DateTime)com.ExecuteScalar(); //将返回转化为 DateTime 类型 Console.WriteLine(dt); //在控制台输出结果
本示例中使用“SELECT NOW()”语句査询出系统当前的时间。然后通过DateTime类型将Object对象直接转换为DataTime类型的数据。执行完后,可以在控制台显示当前系统的时间。
如果希望将object对象转换为String类型,那就必须强制转换成String类型。如果查询语句使用SUM()和AVG()时,最好将object对象转换为Decimal类型。
【示例21-7】下面通过ExecuteScalar()方法计算score表的总成绩。其部分代码如下:
//创建MySqlCommand对象,并且将这个对象实例化 MySqlCommand com = new MySqlCommand("SELECT SUM(grade) FROM score",conn); decimal sum = (Decimal)com.ExecuteScalar(); //将返回转换为 Decimal 类型 Console.WriteLine(sum); //在控制台输出结果
执行完后,可以在控制台显示score表的总成绩。查询语句使用COUNT()函数时,这个查询语句的返回值不能转换为Dedmal类型。可以通过两次转换的方式将其转换为int类型。先将object对象转换为long类型,然后再转换为int类型。
【示例21-8】下面通过ExecuteScalar()方法计算student表的学生数。其部分代码如下:
MySqlCommand com = new MySqlCommand("SELECT COUNT(*) FROM student", conn); int sum = (int)(long)com.ExecuteScalar(); Console.WriteLine(sum);
通过两次转换,可以将返回的object对象转换为int类型。执行完后,可以在控制台显示sum变量的值。
21.2.6处理带参数的SQL语句
C#中可以执行带参数的SQL语句。带参数的SQL语句中可以不指定某个字段的值,而使用问号(?)和变量名代替,例如"?var"就是一个参数。可以通过Add()方法为参数赋值,其代码的基本形式如下:
com.CommandText="INSERT INTO table(name1, name2) VALUES(?name1, ?name2)"; com.Parameters.Add("?name1", value1); com.Parameters.Add("?name2", value2); com.ExecuteNonQuery();
但是,这种方式只能执行一个INSERT语句。
【示例21-9】下面使用带参数的INSERT语句向score表中插入一条记录。其部分代码如下:
MySqlCommand com; //创建 MySqlCommand 对象 com.Connection = conn; //将 conn 传递给 com 的 Connection 属性 //com对象通过CommandText获取INSERT语句。INSERT语句中的问号(?)加变量表示待输入的参数 com.CommandText="INSERT INTO score(id, stu_id, c_name, grade) VALUES(?id, ?stu_id,?c_name, ?grade)"; com.Parameters.Add("?id", 19); //给参数赋值 com.Parameters.Add("?stuJd", 909); com.Parameters.Add("?c_name", "体育"); com.Parameters.Add("?grade", 90); com.ExecuteNonQuery(); //执行带参数的 INSERT 语句
如果需要执行多个INSERT语句,那么必须要使用MySqlParameter对象。这里可以通过 Add()函数为SQL语句中参数设置数据类型。然后通过Prepare()方法对SQL语句进行处理, 再通过Value属性参数赋值,其代码的基本形式如下:
MySqlParameter p_name1, p_name2; com.CommandTexT="INSERf INTO table(name1, name2) VALUES(?name1, ?name2)"; p_name1= Parameters.Add("?name1", DataType); p_name2= Parameters.Add("?name2", DataType); com.Prepare(); p_name1 .Value=value1; p_name2.Value=value2; com.ExecuteNonQuery();
【示例21-10】下面使用带参数的ENSERT语句向score表中插入两条记录。其部分代码如下:
MySqlParameter p_id, p_stu, p_name, p_grade; //创建 MySqlParameter 对象 MySqlCommand com; //创建 MySqlCommand 对象 com.Connection = conn; //将 conn 传递给 com //com对象通过CommandText获取INSERT语句。INSERT语句中的问号(?)加变量表示待输入的参数 com.CommandText="INSERT INTO score(id, stu_id, c_name, grade) VALUES(?id, ?stuJd,?c_name, ?grade)"; p_id=com.Parameters.Add("?id", MySqlDbType.lnt32); //设置参数的数据类型 p_stu=com.Parameters.Add("?stu_Id", MySqlDbType.lnt32); p_name=com.Parameters.Add("?c_name", MySqlDbType.VarChar); p_grade=com.Parameters.Add("?gradew", MySqlDbType.lnt32); com.Prepare(); //使用Prepare()方法处理INSERT语句 pJd.Value=19; //使用Value属性将值传递给参数 p__stu.Value=908; p_name.Value=1"体育"; p_grade.Value=90; com.ExecuteNonQuery(); //执行 INSERT 语句 p_id.Value=20; //使用Value属性将值传递给参数 p_stu.Value=908; p_name.Value="数学"; p_grade.Va!ue=90; com.ExecuteNonQuery(); //执行第二个 INSERT 语句
本示例中可以向score表中插入两天记录。
21.2.7 使用 DataSet对象和DataTable对象
DataSet对象和DataTable对象可以更方便的读取査询结果。而且,可以其中插入、更新、删除数据。一个DataSet对象可以管理一个或者多个DataTable对象。DataSet和DataTable是ADO .NET的类,它们属于命名空间System.Data。因此需要使用using语句引入 System.Data。其语句如下:
using System.Data;
需要使用MySqlDataAdapter对象获取MySqlCommand对象,并且创建DataSet对象和 DataTable对象。语句如下:
MySqlDataAdapter da = new MySqlDataAdapter(com); DataSet ds = new DataSet(); DataTable dt = new DataTable();
MySqlDataAdapter对象调用Fill()方法执行SELECT语句,并且将查询结果存入DataSet对象中,然后通过DataTable对象来处理数据。调用Fill()方法和使用DataTable对象的语句如下:
da.Fill(ds,"tableName"); dt = ds.Tables["tableName"];
然后就可以从DataTable对象dt中读取数据了。
【示例21-11】下面通过MySqlDataAdapter对象查询student表的所有记录。然后通过DataSet对象和DataTable对象将查询结果输出到控制台。其部分代码如下:
MySqlDataAdapter da = new MySqlDataAdapter(com); DataSet ds = new DataSet(); DataTable dt = new DataTable(); da.Fill(ds,"student_info"); dt = ds.Tables["student_info"]; for (int i = 0; i < dt.Rows.Count; i++) Console.WriteLine(dt.Rows[i][Mid"].ToString()+" "+dt.Rows[i]["name"].ToString()+"+dt.Rows[i]fdepartmenn.ToString());
其中,DataSet对象中的表取个別名为student_info。dt.Rows.Count()可以获取dr中有多少条记录。dt.Rows[i]["id"].ToString()表示从dt的第i行记录中获取id字段的值,将获取的值转换为字符串。然后,将获取的值在控制台输出。
21.2.8 关闭创建的对象
如果不关闭MySQLConnection对象和MySqlDataReader对象,这些对象会一直占用系统资源。如果不需要使用这些对象时,必须将这些对象关闭。这些对象可以调用Close()方法来关闭对象。关闭MySQLConnection对象和MySqlDataReader对象的语句如下:
conn.Close(); dr.Close();
关闭了MySQLConnection对象和MySqlDataReader对象后,他们所占用的内粗资源和其他资源就被释放掉了