知识点:DataReader对象的常用属性和方法、利用Command对象生成DataReader对象、ExecuteReader()方法的使用。
1、使用DataReader对象查询数据
DataReader是只读只进的读取器,也就是说它只能读取数据而不能修改数据,并且只能从前往后读取,而不能反过来读取数据,每次读取一行数据。DataReader的特点是:读取数据比较快,但是需要一直保持数据库连接。
和Connection对象一样,不同的数据库产品,对应有不同的数据源,因此对应不同的DataReader。SQLServer的命名空间是System.Data.SqlClient 对应的是SqlDataReader类。
命名空间 | 对应的 DataReader 对象 |
System.Data.SqlClient | SqlDataReader |
System.Data.OleDb | OleDbDataReader |
System.Data.Odbc | OdbcDataReader |
System.Data.OracleClient | OracleDataReader |
1.1 为什么使用DataReader?
使用Command对象的ExecuteScalar方法可以实现单个值的查询(只能返回一行一列的结果),那么遇到要查询数据中多个数据的情况该怎么办呢?比如我要将数据里的关于毛毛的信息(姓名、学校、成绩)都提取出来,这里就要用到DataReader对象了。
1.2 DataReader对象的主要属性和方法
属性 | 说明 |
HasRows | 是否返回了结果 |
方法 | 说明 |
Read | 前进到下一行记录 |
Close | 关闭 DataReader 对象 |
1.3 使用DataReader对象对数据库进行查询操作步骤
- 创建Connection对象
- 给Connection对象添加属性
- 调用Connection对象Open()方法打开数据库
- 创建sql语句字符串
- 创建Command对象 SqlCommand cmd = new SqlCommand(sql语句, Connection对象);
- 执行命令,获得DataReader对象,语法:SqlDataReader 读取器对象名=命令对象(Command对象名).ExecuteReader();
- 使用循环,调用DataReader对象的Read方法,逐行读取数据。(Read方法具有bool类型的返回值。若能读取到数据,则返回true,否则返回false.)
- 获取当前数据库表每一行的某一列数据,(可以使用索引或列名来获取当前的某一行数据,索引从0开始,且获取数据时需要进行显式类型转换。) 语法:读取器对象名[索引或列名];
- 使用完毕后关闭DataReader对象(数据读取完毕必须关闭DataReader对象,因为在读取数据时,DataReader对象将独占连接,此时,就无法使用当前连接对象执行其他操作。) 语法:读取器对象名.Close();
- 关闭数据库连接对象。 语法:连接对象名.Close();
2、DataReader对象使用实例
实例练习:点击按钮,显示数据库表中的学生信息。
第一步:有数据。使用SQL语句创建数据库、数据库表、并向表中插入一些数据
--创建数据库
create database StudentDB;
--使用数据库
use StudentDB;
--创建数据库表StudentInfo
create table StudentInfo(
Id int primary key identity(1,1),
Names nvarchar(20) not null,
Class nchar(8) not null,
Score int not null
);
--向表StudentInfo中插入几行数据
insert into StudentInfo(Names,Class,Score)
select '张三','1831301',92 union
select '李四','1831302',52 union
select '王五','1831303',78 union
select '赵六','1831304',83 ;
第二步:有应用程序。在VS软件中新建项目,并设计程序。
(1)新建一个窗体应用程序
(2)对Form1窗体进行设计。分别添加一个button控件和label控件,并设置label控件的Text属性为空。
第三步:编写代码,给button按钮添加点击事件。
private void button1_Click(object sender, EventArgs e)
{
//1.创建Connection对象
SqlConnection con = new SqlConnection();
//2.给Connection对象添加属性
con.ConnectionString = "data source=LAPTOP-IN3E6IJP\\SQLEXPRESS; initial catalog=StudentDB; integrated security=true";
try
{
//3.调用Connection对象Open()方法打开数据库
con.Open();//打开数据库
MessageBox.Show("数据库连接成功");
//4.创建sql语句字符串
string chaxun = "select * from StudentInfo;";
//5.创建Command对象
SqlCommand com = new SqlCommand(chaxun, con);
//6.执行命令,获得DataReader对象
SqlDataReader reader = com.ExecuteReader();
//7.使用循环,调用DataReader对象的Read方法,逐行读取数据
while (reader.Read())
{
//8.获取数据库表行中的某一列数据
string shuchu = Convert.ToString(reader[0]+"," + reader[1] + "," + reader[2] + "," + reader[3]);
//将获取的数据输出,赋值给label对象的Text属性
label1.Text += shuchu+"\n";
}
//9.关闭DataReader对象
reader.Close();
}
catch (Exception a)
{
MessageBox.Show(a.Message);
}
finally
{
//10.关闭Connection对象
con.Close();//关闭数据库
}
}
3、DataReader对象使用实例
实例练习:把数据库表中的班级信息,填充到窗体控件上
第一步:在Form1窗体中,添加一个ComboBox控件
第二步:双击Form1窗体,进入窗体Load事件,编写代码
private void Form1_Load(object sender, EventArgs e)
{
//1.创建Connection对象
SqlConnection con = new SqlConnection();
//2.给Connection对象添加属性
con.ConnectionString = "data source=LAPTOP-IN3E6IJP\\SQLEXPRESS; initial catalog=StudentDB; integrated security=true";
try
{
//3.调用Connection对象Open()方法打开数据库
con.Open();//打开数据库
//4.创建sql语句字符串
string chaxun = "select * from StudentInfo;";
//5.创建Command对象
SqlCommand com = new SqlCommand(chaxun, con);
//6.执行命令,获得DataReader对象
SqlDataReader reader = com.ExecuteReader();
//7.使用循环,调用DataReader对象的Read方法,逐行读取数据
while (reader.Read())
{
//8.获取数据库表行中的某一列数据,并将它添加到comboBox1控件集合里
comboBox1.Items.Add(reader["Class"]);//reader["Class"]等同于reader[2]
}
//9.关闭DataReader对象
reader.Close();
}
catch (Exception a)
{
MessageBox.Show(a.Message);
}
finally
{
//10.关闭Connection对象
con.Close();//关闭数据库
}
}
此处代码和上一个案例的代码几乎相同,只是在第八步有区别:
//8.获取数据库表行中的某一列数据,并将它添加到comboBox1控件集合里
comboBox1.Items.Add(reader["Class"]);//reader["Class"]等同于reader[2]
思考:这样情况下,我们重复的写了大量的重复代码,有什么办法可以让我们的代码编写工作量小一些?
============这里是结束分割线===============