相信我们对SqlHelper已不再陌生,SqlHelper被称为“数据库小助手”。我们可以在很多项目中看到它,但我们跟着牛腩老师做完牛腩系统后,品味他所教给我们的SqlHelper。可以用完美、简单来概括。
用构造函数定义公共的数据库连接对象。
用统一的方法,处理不同类型数据
SqlConnection 类 |
到 SQL Server 数据库的打开的连接。 此类不能被继承。 |
SqlCommand类 |
对 SQL Server 数据库执行的一个 Transact-SQL 语句或存储过程。 此类不能被继承。 |
SqlDataReader类 |
提供一种从 SQL Server 数据库读取行的只进流的方式. |
CommandBehavior 枚举 |
提供对查询结果和查询对数据库的影响的说明。 |
<span style="font-size:18px;">/* * 制作人:高晓青 * 创建时间:2013年10月1日 13:46 * 说明:数据库助手类 * 版权所有:高晓青 */ using System; usingSystem.Collections.Generic; using System.Linq; using System.Text; usingSystem.Threading.Tasks; using System.Data; usingSystem.Data.SqlClient; usingSystem.Configuration; namespace DAL { public class SQLHelper { //通过构造函数实例化所需要的ADO对象 private SqlConnection conn = null; private SqlCommand cmd = null; private SqlDataReader sdr = null; //将连接数据对象封装在构造函数里 public SQLHelper() { //连接数据库的字符串(配置文件中获取) string connStr =ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; //连接数据库对象 conn = new SqlConnection(connStr); } /// <summary> /// 得到连接数据库对象 /// </summary> /// <returns>返回连接数据对象</returns> private SqlConnection GetConn() { if (conn.State ==ConnectionState.Closed) { conn.Open(); } return conn; } /// <summary> /// 该方法执行不带参数的增删改SQL语句或存储过程 /// </summary> /// <paramname="sql">增删改SQL语句或存储过程,传入参数数组</param> /// <returns>命令类型,影响行数</returns> public int ExecuteNonQuery(stringcmdText,CommandType ct) { //定义变量 int res; //使用try…catch语句,使用完数据库后关闭数据库 try { //将SQL语句与连接对象传入执行查询对象 cmd = new SqlCommand(cmdText,GetConn()); //执行数据库的操作类别 cmd.CommandType = ct; //执行查询,返回受影响的行数 res = cmd.ExecuteNonQuery(); } catch (Exception ex) { throw ex; } finally { //关闭数据库 if (conn.State ==ConnectionState.Open) { conn.Close(); } } return res; } /// <summary> /// 执行带参数的增删改SQL语句或存储过程 /// </summary> /// <paramname="sql">增删改SQL语句或存储过程</param> /// <paramname="paras">命令类型</param> /// <returns></returns> public int ExecuteNonQuery(stringcmdText, SqlParameter[] paras, CommandType ct) { //定义返回影响函数变量 int res; //using语句执行SQL语句 using (cmd = newSqlCommand(cmdText, GetConn())) { //执行数据库的操作类别 cmd.CommandType = ct; //加载参数 cmd.Parameters.AddRange(paras); //执行查询并返回受影响的行数 res = cmd.ExecuteNonQuery(); } return res; } /// <summary> /// 该方法执行传入的SQL查询语句 /// </summary> /// <paramname="sql">SQL查询语句或存储过程</param> /// <returns></returns> public DataTable ExecuteQuery(stringcmdText, CommandType ct) { //实例化datatable对象 DataTable dt = new DataTable(); //传入需要执行的SQL语句与连接数据库对象 cmd = new SqlCommand(cmdText,GetConn()); //定义执行的类型 cmd.CommandType = ct; using (sdr =cmd.ExecuteReader(CommandBehavior.CloseConnection)) { //将查询结果加载到dt中 dt.Load(sdr); } return dt; } /// <summary> /// 该方法执行带参数的SQL查询语句 /// </summary> /// <paramname="sql"></param> /// <returns></returns> public DataTable ExecuteQuery(stringcmdText, SqlParameter[] paras, CommandType ct) { //实例化datatable对象 DataTable dt = new DataTable(); //传入需要执行的SQL语句与连接数据库对象 cmd = new SqlCommand(cmdText,GetConn()); //定义执行类型 cmd.CommandType = ct; //参数加载 cmd.Parameters.AddRange(paras); //将查询结果加载到dt using (sdr =cmd.ExecuteReader(CommandBehavior.CloseConnection)) { dt.Load(sdr); } //返回查询结果 return dt; } } }</span>
<span style="font-size:18px;">1、通过构造函数实例化sqlhelper private SQLHelper sqlhelper; public NewsDAO() { sqlhelper = new SQLHelper(); } 2、无参数的查询 #region选择全部新闻 /// <summary> /// 选择全部新闻 /// </summary> /// <returns></returns> public DataTable SelectAll() { //定义dt用来存储返回数据 DataTable dt = new DataTable(); //sql语句 string sql = "select * fromnews"; //调用sqlhelper中封装好的方法 dt = newSQLHelper().ExecuteQuery(sql, CommandType.Text); //返回受影响函数 return dt; } #endregion 3、有参数的查询 #region 根据类别ID取出该类别下的所有新闻 /// <summary> /// 根据类别ID取出该类别下的所有新闻 /// </summary> /// <paramname="id"></param> /// <returns></returns> public DataTable SelectByCaId(stringcaid) { //TODO:根据类别ID取出该类别下的所有新闻 DataTable dt = new DataTable(); //定义存储过程 string procName ="News_SelectByCaId"; //定义需要传入的参数 SqlParameter[] paras = newSqlParameter[]{ newSqlParameter("@caid",caid)}; //调用封装好的方法 dt =sqlhelper.ExecuteQuery(procName, paras, CommandType.StoredProcedure); //返回受影响的行数 return dt; } #endregion 4、无参数的删除 /// </summary> /// <paramname="Id">评论所属的新闻编号</param> ///<returns>布尔值</returns> public Boolean Delete(stringId) { Boolean flag = false; string sql = "delete fromcomment where newsId='Id'"; int res =sqlhelper.ExecuteNonQuery(sql, CommandType.Text); if (res > 0) { flag = true; } return flag; } 5、有参数的删除 /// <summary> /// 删除类别(联通其下的新闻及新闻评论一起删除) /// </summary> /// <paramname="id"></param> /// <returns></returns> public bool Delete(string id) { //定义bool变量并赋初值 bool flag = false; //sql语句 string sql = "delete fromcategory where id=@id"; //传入参数 SqlParameter[] paras = newSqlParameter[]{ new SqlParameter("@id",id)}; //调用方法 int res =sqlhelper.ExecuteNonQuery(sql, paras, CommandType.Text); //连续按两下Tab可以显示代码段 if (res > 0) { flag = true; } return flag; }</span>
四、SqldataReader扩展
1、数据库连接
(1)SqlDataReader未关闭前,数据库连接会一直保持打开状态,所以使用完毕应马上调用SqlDataReader.Close()关闭它。
(2)一个连接只能被一个SqlDataReader使用,应尽早关闭。
(3)使用完SqlDataReader后,关闭方法:
<1显示的调用数据库连接对象的Close方法关闭连接
<2调用Command对象的ExecuteReader方法时传递CommandBehavior.CloseConnection这个枚举变量,这样在调用SqlDataReader的Close方法时会自动关闭数据库连接。
(4)使用SqlDataReader获取多条记录时,如果没有访问到取出记录的末尾时想要关闭SqlDataReader,应该先调用Command对象的Cancel方法,然后再调用SqlDataReader的Close方法。Command对象的Cancel方法使得数据库不再把SqlDataReader中未访问的数据发送到调用端,如果不调用此方法直接关闭SqlDataReader,数据库会发送和SqlDataReader未访问数据等长的空数据流到调用端。
2、参数传递
(1)使用SqlDataReader时尽量使用和数据库字段类型匹配的方法来取得相应的值,比如对于整形的字段使用GetInt32,对字符类型的字段使用GetString。这样会减少因为类型不一致而额外增加的类型转换操作。
(2)如果想通过SqlCommand的ExecuteReader方法获取存储过程的返回值或者输出参数,必须先调用SqlDataReader的Close方法后,才能获取输出参数的值或者返回值。
(3)如果使用SqlDataReader只返回一条记录,那么在调用Command的ExecuteReader方法时,指定CommandBehavior.SingleRow参数,这个参数的是否使用对SQL Server .NET Data Provider没有什么影响,但是当你使用OLEDB .NET Data Provider时,指定这个参数后,DataPrivider内部将使用IRow接口,而不是使用相对来说耗费资源的IRowSet接口。