重难点:reader.NextResult()、反射揭示连接池原理、连接字符串写法
一、日期函数:
1、getdate() 获得当前日期
2、Dateadd(datepart,number,date)
--查询出入职日期一年以上的
select * from TblStudent
where dateadd(year,1,tsBirthday)<getdate()
3、datediff(datepart,startpart,endpart)
4、year(tsBirthday)
month()
hour()
datepart(month,getdate())
datepart(date,getdate())
datepart(minute,getdate())
datepart(second,getdate())
datepart(ms,getdate())
二、ADO.Net
(一)常用类:Connection、Command、DataReader、DataAdapter(是对前三个类的封装)、DataSet(数据集)
其他常见类:
ConnectionStringBuilder 自动生成连接字符串
Parameter 带参数的SQL语句
Transaction 在ADO.NET中使用事务
与DateSet相关的类:
DataView 视图类,DataTable中的数据以不同的视角查看
DataRowView DataView中的行
DataTable DataSet中的数据表
DataRow DataTable中的行
DataColumn DataTable中的列
DataRelation DataTable与DataTable的关系
Constraint DataTable中建立的约束
(二)连接数据库(Connection)
1、 连接字符串
//使用sql server身份验证方式
string constr = “Data Source=ZXTIGER;Initial Catalog=ItCastCn;User Id=sa;Password=sa”;
//使用windows身份验证方式
string constr=”Data Source= ZXTIGER;Initial Catalog=ItCastCn;Integrated Security=True”;
2、 根据连接字符串,创建连接对象
SqlConnection con = new SqlConnection(constr);
//这句话才是去连接数据库的操作,如果失败也是这句话报异常
con.Open();
Console.WriteLine(“打开成功!”);
con.Close();
con.Dispose();
Console.WriteLine(“成功关闭!”);
Console.ReadKey();
或用using:
using(SqlConnection con = new SqlConnection(constr))
{
//不能重复打开连接对象,可以重复关闭。
con.Open();
…
}
3、 生成连接字符串(SqlConnectionStringBuilder)
SqlConnectionStringBuilder csBuilder = new SqlConnectionStringBuilder();
csBuilder.DataSource = “zxtiger”;
csBuilder.UserID = “sa”;
csBuilder.Password = “sa”;
csBuilder.InitialCatalog = “itcastcn”;
csBuilder.ConnectTimeout = 30;
Console.WriteLine(csBuilder.ConnectionString);
Console.ReadKey();
(三)Command对象、SqlDataReader对象
1、ExecuteNonquery
2、ExecuteReader 返回SqlDataReader。
关于SqlDataReader:
a、每向前走一条都会将上一条记录销毁,所以DataReader是只进的。b、SqlDataReader只能读取数据不能修改数据,因为查询出的数据集是一个独立的在内存中的数据。
(1)GetValue与Reader索引器
reader.GetValue(0)与reader[0]等价
reader[“EmpGender”]
--一般使用索引来获取列的信息,不使用列名(效率低)。
--如果必须使用列名,可以先在循环外根据列名获取索引(GetOrdinal),再在循环里根据索引获取数据。
int index = reader.GetOridinal(columnName);
reader.GetValue(index);
(2)使用强类型的GetString()、GetInt32、GetFloat()、GetDouble()
--当前列如果为null,调用强类型获取数据的方法就会报错,需要获取数据前做一个判断,reader.IsDbNull()
(3)同时查询多张表,返回多个结果集,用NextResult循环输出(本例只是输出,也可以用reader.GetValue(i),不必输出)
do
{
if (reader.HasRows)
{
while (reader.Read())
{
//循环列
for (int i = 0; i < reader.FieldCount; i++)
{
string dbType = reader.GetDataTypeName(i);
switch (dbType)
{
case "varchar":
case "nvarchar":
case "char":
case "nchar":
Console.Write(reader.GetString(i) + "\t");
break;
case "int":
Console.Write(reader.GetInt32(i) + "\t");
break;
case "datetime":
Console.Write(reader.GetDateTime(i) + "\t");
break;
}
}
Console.WriteLine(); ;
}
}
}
while(reader.NextResult());
3、ExecuteScalar 内部是调用ExecuteReader实现的
--执行插入语句返回刚刚生成的自动编号
insert into TblClass output inserted.tclassId values(‘黑马5期’,’正在热招中…’);
--执行任何sql语句调用三种方法的任何一种都行,但调用适当的方法才能返回期望的查询结果。
(四)异常处理
连接对象,如果写在using语句中,即使发生异常,当using语句退出时也会调用Dispose()方法,会释放资源,所以可以在using中使用连接对象,不用写try-catch。
(五)ADO.Net中一般会出两类错误:
1、连接字符串写错
2、sql查询语句写错
(六)登录练习
sql语句:
select count(*) from UserLogin
where loginId=’zxh’ and loginPwd=’jk123’
(七)ADO.Net连接池
1、 启用连接池和禁用连接池为什么性能差距这么大?
(1) 启用连接池后,只有一次打开(当程序关闭后才会关闭),性能高。
(2) 禁用连接池后,是真的打开关闭了2000次。
2、通过反射揭示原理:
string constr = “Data Source=zxtiger;Initial Catalog=Itcastcn;Integrated Security=True”;
//通过反射来访问SqlConnection的私有属性InnerConnection
PropertyInfo pInfo=typeof(SqlConnection).GetProperty(“InnerConnection”,BindingFlags.NonPub lic|BindingFlags.Instance);
object obj1 = null;
object obj2 = null;
SqlConnection con1 = new SqlConnection(constr);
using(con1)
{
con1.Open();
//获取con1内部的InnerConnection对象
obj1 = pInfo.GetValue(con1,null);
con1.Close();
}
SqlConnection con2 = new SqlConnection(constr);
using(con2)
{
con2.Open();
//获取第二个对象的InnerConnection
obj2 = pInfo.GetValue(con2,null);
con2.Close();
}
if(obj1==obj2)
{
Console.WirteLine(“是同一个对象”);
}
else
{
Console.WriteLine(“不是同一个对象”);
}
Console.ReadKey();
3、连接池总结:
(1) 第一次打开连接会创建一个连接对象
(2) 当这个连接关闭时,会将当前连接对象放入池中
(3) 下一个连接对象,如果连接字符串与池中现有的完全一致,则使用池中连接。
(4) 只有对象调用Close()才会放入池中,如果一个对象一直使用,则创建一个新的连接即使连接字符串一样,也新建一个连接字符串。