6-16 ADO.NET基础和连接池

================================ADO.NET============================
 
一创建连接对象Connection
1.创建连接字符串:
string constr=@"Data Source=.\SQLEXPRESS; Initial CataLog=ccdb; user id=sa;password=sa;";
视图-服务器自愿管理器-数据连接-右击-找名字-数据库密码-高级
2.连接数据库
SqlConnection con=new SqlConnection(constr);
3.打开数据库;
con.Open();
只能打开一次 不能重复打开
由于SqlConnection继承了DbConnection类,而DbConnection实现了IDisposable接口  所以需要  con.Close(); con.Dispose();  可以重复关闭
 
====以上的方法比较麻烦  为了简便  用using
using(SqlConnection con=new SqlConnection(constr))
1.连接字符串不能重复打开,因此需要判断一下
if (con.State == System.Data.ConnectionState.Closed)
{
con.Open();
}

  


2.每次状态改变的时候打印一下状态
con有个事件改变函数
View Code
1 con.StateChange += new System.Data.StateChangeEventHandler(con_StateChange);
2 static void con_StateChange(object sender, System.Data.StateChangeEventArgs e)
3 {
4 Console.WriteLine(e.CurrentState.ToString());
5 }

 


4.连接字符串是通过这个生成的(很多时候看这个可以)
1             SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
2             scsb.DataSource =@".\SQLEXPRESS";
3             scsb.UserID = "sa";
4             scsb.Password = "sa";
5             scsb.InitialCatalog = "ccdb";
6             scsb.ConnectTimeout = 30;
7             Console.WriteLine(scsb.ConnectionString);
8             Console.ReadKey();

 


5.自己动手创建
  
 1  private void button1_Click(object sender, EventArgs e)
 2 {
 3 SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
 4 propertyGrid1.SelectedObject = sqlBuilder;
 5 }
 6  
 7 private void button2_Click(object sender, EventArgs e)
 8 {
 9 SqlConnectionStringBuilder sb = (SqlConnectionStringBuilder)propertyGrid1.SelectedObject;
10 MessageBox.Show(sb.ConnectionString.ToString());
11 }

 

----SqlDataReader
1.只读,每次向前走一条都会将上一条记录销毁,所以DataReader是只进的。
2.只读,只能读取数据不能修改数据
在Reader使用过程当中必须保证connection是打开状态
reader.Value(0)=reader[0]
reader["列名"] 内部实现
string colunmName="EmpGender";
根据列名获取索引,然后再根据索引调用GetValue();
int index=reader.GetOrdinal(colunmName);
reader.value(index);
一般没有特殊情况建议使用索引来获取,不要使用  列名效率比较低
高效 在while外
int i1=reader.GetOrdinal("列1");
int i2=reader.GetOrdinal("列2");
注意:一定不要在循环内写列名
====读取一个结果集
在while中循环
for(int i=0;i<reader.FieldCount;i++)
{
console.write(reader.GetValue(0));
}
console.writeLine();
====获取多个结果集
 
 1                        do
 2                         {
 3                             if (reader.HasRows)
 4                             {
 5                                 while (reader.Read())
 6                                 {
 7                                     //循环列
 8                                     for (int i = 0; i < reader.FieldCount; i++)
 9                                     {
10  
11                                         //根据索引,获取列名
12                                         //reader.GetName(i);
13                                         //获取当前列的数据类型
14                                         string dbType = reader.GetDataTypeName(i);
15                                         switch (dbType)
16                                         {
17                                             case "varchar":
18                                             case "nvarchar":
19                                             case "char":
20                                             case "nchar":
21                                                 Console.Write(reader.GetString(i) + "\t");
22                                                 break;
23                                             case "int":
24                                                 Console.Write(reader.GetInt32(i) + "\t");
25                                                 break;
26                                         }
27                                     }
28                                     Console.WriteLine();
29                                 }
30                             }
31                         } while (reader.NextResult()); 

 

//当多个结果集的时候可以调用NextResult
==dataReader 独享数据连接
DataReader 必须独享一个Connection 。(除非设置了允许MARS,多活动结果集,在连接字符串中)
 
必须在连接字符串中设置,把多活动结果集设为true
 
IsDbNull
 //当前列如果为null的话,调用强类型的获取数据的方法就报错了。,就需要获取数据之前做一个判断;通过reader.IsDBNull(index)来验证
string obj3 = reader.IsDBNull(2) ? "空" : reader.GetString(2);
----异常处理
在reader中从open开始都可能出现异常,但是这个时候已经open了,所以为避免崩溃  写在catch中  但是出现异常  无论怎样都要关闭,因此一定要在finally中 关闭
con.Close();con.Dispose()
----返回的是单行单列
ExecuteScalar() 内部对Reader的封装
执行刚插入生成的自动编号
insert into Tblclass output inserted tclassid  values('河马','热招中。。')
执行任何sql语句其实调用 SqlCommand 对象的ExecuteNonQuery(), ExecuteScalar() ExecuteReader() 都可以,只不过是执行对应的语句,如果选对了方法使用起来更合适
最好不用 (int)obj(拆箱,如果装箱时不是int类型,就报错了) 建议是用convert.toint32(obj);
 
=========================ADO.NET连接池==============================
连接池
//1.启用连接池与禁用连接池为什么性能差距这么大?Pooling=false
//1.当启用连接池后,看似是2000次的登录与注销(连接的打开与关闭),其实只有一次打开,(当程序关闭后才会关闭)。所以高性能
//2.而禁用连接池后,则是真正的打开关闭了2000次。
当Close方法的时候会将当前的连接对象放入到连接池中,当下次再创建一个连接对象,如果该连接对象所使用的连接字符串与场次连接对象的连接字符串完全一致(必须完全一致,包括大小写,空格等),这时,其实并不会真正的再创建一个到数据库的连接,而是会使用连接池中现有的连接;
 
;ADO.NET 连接池使用总结
1.第一次打开连接会创建一个连接对象
2.当这个连接关闭时(调用Close()方法时)会将当前连接对象放入池中。
3.下一个连接对象,如果连接字符串与池中现有连接对象的连接字符串完全一致,则会使用池中的现有连接,而不会重新创建一个
4.只有对象调用Close()的时候才会放入池中,如果一个连接对象一直在使用,则下次再创建一个连接对象发现池中没有,会再创建一个。
5.在连接池中,如果过一段时间没有访问自动销毁
 
反射:
 PropertyInfo pinfo = typeof(SqlConnection).GetProperty("InnerConnection", BindingFlags.NonPublic | BindingFlags.Instance);
获取反射后的值
 
object obj1 = null;
    object obj2 = null;
//获取第二个对象的InnerConnection
         obj2 = pinfo.GetValue(con2, null);
每个用户使用不同的连接字符串,建议禁用连接池
 
清空连接池:
SqlConnection.ClearAllPools();
        SqlConnection.ClearPool();
 
posted @ 2012-07-26 19:13  51秒懂  阅读(243)  评论(0编辑  收藏  举报