第七章第 1 节: ADO.Net简介 MYSQL的.Net驱动mysql-connector-net-***.msi下载地址:
1)http://www.cncrk.com/downinfo/41149.html
2)http://www.cr173.com/soft/50789.html
3)http://dev.mysql.com/downloads/file.php?id=405442
4)http://download.csdn.net/detail/du_niao/6500785
新建项目,添加引用→“扩展”,添加Mysql.Data;如果是直接解压版,然后直接添加对MySql.Data.dll文件的引用;
123456789
using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database=study1;uid=root;pwd=root;Charset=utf8"))
using (MySqlCommand cmd = conn.CreateCommand())
{
conn.Open();//一定要在执行前Open数据库连接
cmd.CommandText = "Insert into T_Users(UserName,Password) values('中国人','123')";
int rowCount = cmd.ExecuteNonQuery();
Console.WriteLine("受影响的行数"+rowCount);
}
解释一下代码:
MySqlConnection、MySqlCommand实现了IDisposable接口,因此使用using进行资源释放;
"Server=localhost;Database=study1;uid=root;pwd=root;Charset=utf8"叫连接字符串,Server是Mysql服务器的地址,Database是连接的数据库,uid、pwd是用户名和密码,采用utf8编码。
conn.Open():在执行MySqlCommand之前一定要先打开数据库连接,否则会报错。
ExecuteNonQuery是执行Update、Insert、Delete等非查询语句,返回值为受影响的行数。
************************************************************************************* using(MySqlCommand cmd = conn.CreateCommand()) { conn.Open();//一定要在执行前打开Open数据库连接 } 解释语法:: 创建一个到数据库执行命令的对象,即:MySqlCommand; 从conn 的 CreateCommand() 创建 MySqlCommand 对象【 推荐用这样的语法,比较简单】
B7第七章 第 2 节: 执行Insert语句
B7第七章 第 3 节: ExecuteScalar的用法
第七章 第 3 节: ExecuteScalar
【【【【ExecuteScalar:执行查询,并返回查询所返回的结果集中第一行的第一列,忽略其他行列。一般用来简单的获得只有【【一行一列】】的查询结果的值。】】】】
案例1:
cmd.CommandText = "Select count(*) from T_Users";
long count = (long)cmd.ExecuteScalar();//这样会产生错误--------int count = (int)cmd.ExecuteScalar();。。类型转换有问题,,可以通过。。断点调试看见cmd(long)
long count =Convert.ToInt64 (cmd.ExecuteScalar());//这样写确保数据类型范围足够大。转化不出错
案例2:
cmd.CommandText = "Select Password from T_Users where UserName='admin'";
string pwd = (string)cmd.ExecuteScalar();
if (string.IsNullOrEmpty(pwd))
{
Console.WriteLine("找不到admin");
}
else
{
Console.WriteLine("admin的密码:" + pwd);
}
*************************************************************************************************************************************
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test数据库ExecuteScalar
{
class Program
{
static void Main(string[] args)
{
using(MySqlConnection conn =new MySqlConnection("Server=localhost;Database=study;uid=root;pwd=root;CharSet=utf8"))
using (MySqlCommand cmd = conn.CreateCommand())
{
/*
conn.Open();
cmd.CommandText = "select count(*) from t_users";
// long count = (long)cmd.ExecuteScalar();
//ExecuteScalar:执行查询,并返回查询所返回的结果集中第一行的第一列,
//忽略其他行列。一般用来简单的获得只有一行一列的查询结果的值。
long count = Convert.ToInt64(cmd.ExecuteScalar());
Console.WriteLine("一共有"+count+"记录");
*/
conn.Open();//只能适合查询只有返回结果为一行一列的查询比较好用这个
cmd.CommandText = "Select Password from T_Users where UserName='admin'";
string pwr = (string)cmd.ExecuteScalar();
if (string.IsNullOrEmpty(pwr))
{
Console.WriteLine("找不到admin");
}
else
{
Console.WriteLine("admin的密码是"+pwr);
}
Console.ReadKey();
}
}
}
}
B7第七章 第 4 节: ExecuteReader
1 第七章 第 4 节: ExecuteReader
2 using MySql.Data.MySqlClient;
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Text;
7 using System.Threading.Tasks;
8
9 namespace TestMysql__ExecuteReader
10 {
11 class Program
12 {
13 static void Main(string[] args)
14 {
15 //不要漏输入东西
16 using(MySqlConnection conn=new MySqlConnection("Server=127.0.0.1;Database=study;uid=root;pwd=root;Charset=utf8;"))
17 using (MySqlCommand cmd = conn.CreateCommand())
18 {
19 conn.Open();//连接必须先打开数据库
20 cmd.CommandText = "Select * from T_Users";
21 using (MySqlDataReader reader = cmd.ExecuteReader())
22 {
23 while (reader.Read())//如果记录不为空,就返回true
24 {
25 // long id = reader.GetInt64(0);//通过数据库中的列号,从0开始,获取主键列的序列号
26 long id = reader.GetInt64("id");//通过数据库中的列名字,获取主键列的序列号
27 string username = reader.GetString(1);//获取姓名列的值
28
29 string password = reader.GetString("password");//获取密码列的字符串
30 Console.WriteLine("Id=" + id + ";UserName=" + username + ";PassWord=" + password);
31 }
32 Console.WriteLine();
33 int ordNumber = reader.GetOrdinal("username");//通过列明字获取,列明的序列号
34 Console.WriteLine("UserName是数据库中的第" + ordNumber + "列;");
35 } Console.ReadKey();
36 }
37 }
38 }
39 }
B7第七章 第 5 节: SQL注入漏洞说明
第七章 第 5 节: SQL注入漏洞说明 select count(*) from t_users where UseName="username" and Password="password" 密码输入:a' or ' a'='a
B7第七章 第 7 节: 参数化查询2
第七章 第 7 节: 参数化查询2
1、参数化查询有点:安全;效率高(SQL预编译); 2、所有的sql中都可以使用参数化查询传递;表名,字段名等不能用参数化进行替换; 3、陷阱:不要用MySqlParameter(string parameterName,object value )的这个构造函数,因为(“Age”,0)会被匹配成MySqlParameter(string parameterName,MySqlType dbType)这个构造函数
/* using(MySqlConnection conn = new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8")) using (MySqlCommand cmd = conn.CreateCommand()) { conn.Open(); cmd.CommandText = "Insert into @p(UserName,Password) values(@un,@pwd)";//;表名,字段名等不能用参数化进行替换; cmd.Parameters.Add(new MySqlParameter { ParameterName = "@p", Value = "t_users" });//;表名,字段名等不能用参数化进行替换; cmd.Parameters.Add(new MySqlParameter { ParameterName="@un",Value="rupeng"}); cmd.Parameters.Add(new MySqlParameter { ParameterName="@pwd",Value="123456"}); cmd.ExecuteNonQuery(); }*/ /* using(MySqlConnection conn = new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8")) using (MySqlCommand cmd = conn.CreateCommand()) { conn.Open(); cmd.CommandText = "Insert into T_Users(UserName,Password,Age) values(@un,@pwd,@Age)"; cmd.Parameters.Add(new MySqlParameter("@un","test1")); cmd.Parameters.Add(new MySqlParameter("@pwd", "321")); //int i = 0; //cmd.Parameters.Add(new MySqlParameter("@Age", i));//正确写法1
// cmd.Parameters.Add(new MySqlParameter("@Age", 0));//错误的写法;有陷阱0
cmd.Parameters.Add(new MySqlParameter("@Age",(object)0));//正确写法2 cmd.ExecuteNonQuery(); }*/
B7第七节第 8 节: 读取数据库中的null值
1 第七节第 8 节: 读取数据库中的null值
2
3 使用IsDBNull获取指定序号的列的值是否为null
4
5 int? age=null;
6
7 if (!reader.IsDBNull(reader.GetOrdinal("Age")))
8
9 {
10
11 age = reader.GetInt32("Age");
12
13 }
14
15
16 using MySql.Data.MySqlClient;
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 using System.Text;
21 using System.Threading.Tasks;
22
23 namespace TestMysql__读取数据库中的null值
24 {
25 class Program
26 {
27 static void Main(string[] args)
28 {
29 using(MySqlConnection conn=new MySqlConnection("server=127.0.0.1;database=study;uid=root;pwd=root;Charset=utf8"))
30 using (MySqlCommand cmd = conn.CreateCommand())
31 {
32 conn.Open();
33 cmd.CommandText = "select * from t_users ";
34 using (MySqlDataReader reader = cmd.ExecuteReader())
35 {
36 while (reader.Read())//如果记录不是null或者为“”就返回true,转到定义
37 {
38 string username = reader.GetString("username");
39 //string password = reader.GetString("password");//这样写的话,当密码为空值的时候,会导致,调试错误
40 string password;
41 if (reader.IsDBNull(reader.GetOrdinal("password")))//获取密码列的列的数值
42 {
43 password = null;
44 }
45 else
46 {
47 //GetString/GetInt32 无法读取数据库中的null值
48 //需要提前用IsDBNull判断
49 password = reader.GetString("password");
50 }
51 int? Age;//若果使用"int?"类型则可以将int类型,转化为null
52 if (reader.IsDBNull(reader.GetOrdinal("Age")))
53 {
54 Age = null;
55 }
56 else
57 {
58 Age = reader.GetInt32("age");
59 }
60 Console.WriteLine("用户名:" + username + ";密码:" +
61 (password==null?"密码为空":password)+"年龄:"+(Age==null?"年龄没有记录":Age.ToString()));
62 //使用了双目运算; 条件?回答1:回答2 “ : ”两边的数据类型要一致
63
64 }
65
66 } Console.ReadKey();
67 }
68
69
70 }
71 }
72 }
B7第七章 第 9 节: 离线结果集入门
1 =第七章 第 9 节: 离线结果集入门
2 1、DataReader是服务器结果集游标的体现,所有查询出来的数据都在MySQL服务器上。好处是:当查询结果数据量大的时候避免占用本地内存。不过大部分项目中都会避免大查询结果,因此缺点就明显了:读取的时候必须保持Connection,不仅用起来麻烦,而且会较长时间占用MySQL服务器的连接资源。
3
4 2、DataSet是一个离线结果集容器,它把结果数据放到本地内存中。因为查询结果可能会包含多个表,因此DataSet包含若干DataTable(ds.Tables)、DataTable包含若干DataRow(dt. Rows)。
5
6 用法1:
7
8
9 DataSet ds = new DataSet();
10 MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
11 adapter.Fill(ds);
12 DataTable table = ds.Tables[0];
13
14
15 DataSet 可以盛放多个查询结果集到DataTable ;DataAdapter还可以对结果进行傻瓜化更新、删除、修改。我们一般查询结果集就一个DataTable, DataAdapter的傻瓜化更新不适合于正式的项目,因此有更简单的用法
16
17 DataTable dt = new DataTable();
18
19 dt.Load(reader);
20
21 把DataTable声明到using外,using外再使用查询结果。
22
23 遍历DataTable:
24
25 for (int i = 0; i < dt.Rows.Count; i++)
26 {
27 DataRow row = dt.Rows[i];
28 string name = row.IsNull("Name")?null:(string)row["Name"];//NULL处理
29 Console.WriteLine("name"+name);
30 }
31
32
33 案例代码:
34
35
36 /*
37 using (MySqlConnection conn =new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8"))
38
39 using (MySqlCommand cmd = conn.CreateCommand())
40 {
41 conn.Open();
42 cmd.CommandText = "select * from t_users";
43 using (MySqlDataReader reader = cmd.ExecuteReader())
44 {
45 DataTable dt = new DataTable();
46 dt.Load(reader);
47 for (int i = 0; i < dt.Rows.Count; i++)
48 {
49 DataRow row = dt.Rows[i];
50 int id = (int)row["Id"];//下标方式获得是object
51 string username = (string)row["UserName"];
52
53 //做很复杂的io操作,把username存到文件中
54 //这样就会长期占据Connection
55
56 // object obj = row["Password"];
57 //if(row["Password"]==DBNull.Value)//返回的不是null,而是DBNull
58
59 //string password = (string)row["Password"];
60 //int age = (int)row["Age"];
61 string password = row.IsNull("Password") ? null : (string)row["Password"];
62 int? age = row.IsNull("Age") ? (int?)null : (int)row["Age"];
63
64 Console.WriteLine("id=" + id + ";Username=" + username
65 +";username="+username+";age="+age);
66 }
67 }
68 }*/
69
70 /*
71 DataTable table = new DataTable();
72 using (MySqlConnection conn =
73 new MySqlConnection("Server=127.0.0.1;Database=study1;uid=root;pwd=root;Charset=utf8"))
74 using (MySqlCommand cmd = conn.CreateCommand())
75 {
76 conn.Open();
77 cmd.CommandText = "select * from t_users";
78 using (MySqlDataReader reader = cmd.ExecuteReader())
79 {
80 table.Load(reader);//加载到table中
81 }
82 }
83
84 for (int i = 0; i < table.Rows.Count; i++)
85 {
86 DataRow row = table.Rows[i];
87 int id = (int)row["id"];
88 string username = (string)row["UserName"];
89 Console.WriteLine(id+":"+username);
90 }
91 */
B7第七章 第 12 节: 实现MysqlHelper
第七章 第 12 节: 实现MysqlHelper
复习前边的知识::
public static void ( int ,params string[ ] strs )
params 关键字前边可以有其他参数,params,必须放在参数的最后一个前面【目的就是该参数可以写,也可以也很多个】,但是,但是调用的时候。前边非可变长度的参数,必须赋值了,才可以调用。。。。
连接字符串一般配置到App.config(网站是Web.config)中的<connectionStrings>段中
使用ConfigurationManager类(添加对System.Configuration的引用)【引用程序集System.Configuration】读取
string connstr =ConfigurationManager.ConnectionStrings["connstr"].ConnectionString
一定要保证【代码中的名字】和【配置文件中的名字】一致(初学者容易犯错的,一般提示“初始化代码错误”这个错误就是因为两者名字不一致造成的)
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ADONETTest2
{
class MySqlHelper
{
private static readonly string connstr =ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;//静态方法初始化字符串connstr
public static MySqlConnection CreateConnection()//通过该方法建立与Mysql数据库的连接,只要是一用该方法就实现了链接数据库
{
//using (MySqlConnection conn = new MySqlConnection(connstr))//这里千万不要使用使用using进行资源的释放,,
MySqlConnection conn = new MySqlConnection(connstr);//建立连接
conn.Open();//打开数据库
return conn;//返回值 为连接conn
}
public static int ExecuteNonQuery(MySqlConnection conn, string sql, params MySqlParameter[] parameters)//引用已经建立的连接,执行sql语句,返回影响的行数
{
using (MySqlCommand cmd = conn.CreateCommand())//用using释放查询语句的资源
{
cmd.CommandText = sql;//引用sql语句
/*
foreach (MySqlParameter p in parameters)//foreach数组遍历;用法:"[ ]"前的数据类型名字 +p+ 关键字in+数组名字parameters
{
cmd.Parameters.Add(p);
}*/
cmd.Parameters.AddRange(parameters);//只要是集合类的都包含此方法AddRange()
return cmd.ExecuteNonQuery();//返回该语句cmd影响的行数
}
}
public static int ExecuteNonQuery(string sql,params MySqlParameter[] parameters)//引用方法内自己建立的连接,执行sql语句,返回影响的行数
{
using (MySqlConnection conn(****) = CreateConnection())//用using释放方法内自己建立的连接
{
return ExecuteNonQuery(conn, sql, parameters);//引用上边代码的第二个方法,此时引用的已建立的连接是这个(****)位置的连接,接着返回影响的行数
}
}
public static object ExecuteScalar(MySqlConnection conn, string sql,params MySqlParameter[] parameters)//引用已经建立的连接,执行sql语句,返回一行一列的值
{
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
return cmd.ExecuteScalar();
}
}
public static object ExecuteScalar(string sql,params MySqlParameter[] parameters)//引用方法内自己建立的连接,执行sql语句,返回一行一列的值
{
using (MySqlConnection conn = CreateConnection())
{
return ExecuteScalar(conn, sql, parameters);
}
}
public static DataTable ExecuteQuery(MySqlConnection conn, string sql,params MySqlParameter[] parameters)//引用已经建立的连接,执行sql语句,返回多行多列的值到一个DataTable中
{
DataTable table = new DataTable();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
table.Load(reader);
}
}
return table;
}
public static DataTable ExecuteQuery{+++}(string sql,params MySqlParameter[] parameters)//引用方法内自己建立的连接,执行sql语句,返回多行多列的值到一个DataTable中
{
using (MySqlConnection conn = CreateConnection())
{
return ExecuteQuery(conn, sql, parameters);//引用{+++}的方法
}
}
}
}
注意:(****)、{+++}为标记符号。。ExecuteQuery意思是 执行查询 返回值是 一张二维表,,,ExecuteNonQuery意思是 执行非查询,即:插入,更新,删除操作 返回值是影响的行数,即整形 int
B7第七章 第 13 节: 获得自动增长字段的值
1 第七章 第 13 节: 获得自动增长字段的值
2 1、使用LAST_INSERT_ID()获取“最后一次插入的自动递增列的值”
3
4 2、需要注意Insert语句和select LAST_INSERT_ID()一定要在要在同一个连接中。
5
6
7 using (MySqlConnection conn = MySqlHelper.CreateConnection())
8 {
9 MySqlHelper.ExecuteNonQuery(conn,
10 "insert into t_users(UserName,Password) values('我几时我','123')");
11 object o = MySqlHelper.ExecuteScalar(conn, "select Last_Insert_Id()");
12 //Last_Insert_Id()是获取当前连接中,最近一次自动递增字段的值
13 ulong id = (ulong)o;//无符号的long
14 Console.WriteLine(id);
15 }
16 可以Insert、LAST_INSERT_ID()在同一个连接中单独执行,也可以把LAST_INSERT_ID()放到insert语句后面用;分割(使用ExecuteScalar执行即可)
17
18 1
19 2
20 ulong id = (ulong)MySqlHelper.ExecuteScalar("insert into t_users(UserName,Password) values('我几时我','123');select last_insert_id()");
21 Console.WriteLine(id);
B7第七章 第 14 节: 事务的原子性
第七章 第 14 节: 事务的原子性 1、using 相当于tyr......finally 2、捕获异常需要try.......catch
事务的几个关键环节:
1)要在一个连接中;
2)启动事务:MySqlTransaction tx = conn.BeginTransaction();
3)操作结束后执行tx.Commit() 提交事务;
4)如果执行出错,则tx.Rollback()回滚(当前事务的操作全部取消)。
using(MySqlConnection conn=MysqlHelper.CreateConnection())
using(MysqlTransaction tx = conn.BeginTransaction())
{
try
{
MysqlHelper.ExecuteNonQuery(conn, "Update t_employees Set salary=salary-100 where name="Tom"");
string s = null;//用于制造异常
s.ToString();
MysqlHelper.ExecuteNonQuery(conn, "Update t_employees Set salary=salary+100 where name="John"");
tx.Commit();//提交全部成功
}
catch (Exception ex)//此处的括号可以省略不写,但是一样
{
tx.Rollback();//发生异常,所有的操作都进行回滚,全部还原回去
console.WriteLine(ex);//打印出异常
}
}
B7第七章第 23 节: ADO.Net连接SQLServer(SoEasy)
第七章第 23 节: ADO.Net连接SQLServer(SoEasy) 1、ADO.Net如何连接SQLServer:SQLServer驱动.Net内置(亲生的);把MySqlConnection换成SqlConnection,MySql***换成Sql***。
2、连接字符串:
server=ip;user id=sa;password=密码;database=db1
3、SQLHelper:把MySql查找替换成Sql就可以了。
4、获得自动增长列的值:Insert into t1(...) output inserted.Id values(.........)
5、(*)如果基于接口编程,只要改动CreateConnection就可以(查询参数以Dictionary<string,object>传递;如果使用Provider,连代码都不用改,改配置文件即可。
6、需要特别注意:SqlServer的事务和mysql事务使用有一点不一样的地方是“需要把BeginTransaction返回的SqlTransaction对象赋值给SqlCommand的Transaction属性”