l 基本的连接使用
l Close与dispose的区别
l Ado.net中五个常用对象
l SqlHelper与MD5Helper
1.关于ADO.NET
1)程序与数据库之间的交互是通过在ADO.NET上执行SQL语句完成的。ADO.NET提供了对各种不同的数据库统一操作的接口。
2)在visual studio 中,通过内嵌mdf文件的方式使用SQL Server
数据库。运行时会自动attach(附加)到数据库上,关闭时会自动分离。
3)数据库文件压缩,打包之前需要断开数据库连接。
2.连接SQL
1)引用命名空间using System.Data.SqlClient;创建SqlConnection 对象,并将连接字符串作为其初始化参数。
连接字符串:指定程序连接的服务器,实例,数据库和用户名密码等。
内嵌mdf文件连接字符串:@"data source=.\sqlexpress;attachdbfilename=datadirectory|database1.mdf;integrated
security=true;user instance=true"
.\sqlexpress表示本机上的sqlexpress实例
\之前为服务器名称 ,sqlexpress为实例名
database1.mdf mdf文件名
attachdbfilename=datadirectory|database1.mdf //附加主数据库文件
Integrated security=true //指定windows身份验证
user instance=true //确定用户实例 尽在express版本中有效
2)创建连接
注意,ADO.net中的连接等资源都实现了IDisposable接口,需要用using来进行资源管理。(实现IDisposable接口的对象需要用using来进行资源释放)
using (SqlConnection conn = new SqlConnection(@"data source=.\sqlexpress;attachdbfilename=
|datadirectory|database1.mdf;integrated security=true;user instance=true"))
{
conn.Open(); //表示打开数据库连接
//程序
}
using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=database2013;Integrated Security=True"))
{
conn.Open();
}
在不使用using的情况下可以用实例的close+dispose方法释放资源。
如果之后在执行过程中看不到执行结果,可以按照如下格式对开头进行修改:
static void Main(string[] args)
{
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
if (dataDir.EndsWith(@"\bin\Debug\")
|| dataDir.EndsWith(@"\bin\Release\"))
{
dataDir=System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
AppDomain.CurrentDomain.SetData("DataDirectory",dataDir);
}
// 写程序、、、
}
连接可以重复关闭不能重复打开。
3.执行SQL语句
1)先创建SqlCommand对象,程序对SQL执行命令
using (SqlConnection conn = new SqlConnection(@"data source=.\sqlexpress;attachdbfilename=
|datadirectory|database1.mdf;integrated security=true;user instance=true"))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = "insert into Table2 (UserName ,PassWord) values ('" + UserName + "','" + PassWord + "')";
cmd.ExecuteNonQuery(); // 执行非查询语句
}
}
Executenonquery 执行修改类SQL语句,并返回受影响的行数(int类型)。一般用于执行insert,update,delete。其他SQL语句返回-1.
Executescalar 执行查询,并返回结果集中第一行第一列的数据。返回值为object类型,一般用于查询表中数据总数,最大值,Count,max,min等。使用时要记得转换成int类型或其他需求类型( convert转换(降低出错几率(转换字符串)))。也可用于OUTPUT insert.(列名)的输出值。(如下例是查询刚才输入的列名下的字段)。
cmd.CommandText = "insert into T_usertable (username,password) output inserted.id values ('admin','888888')"; Console.WriteLine(cmd.ExecuteScalar());
输出刚才插入的数据的Id.
Executereader 执行有多行结果集的查询。
using (SqlConnection conn = new SqlConnection(@"data source=.\sqlexpress;attachdbfilename=
|datadirectory|database1.mdf;integrated security=true;user instance=true"))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = "select * from Table2";
using (SqlDataReader reader =cmd.ExecuteReader())
{
while (reader.Read())
{
string username = reader.GetString(reader.GetOrdinal("UserName"));
int id =reader.GetInt32(reader.GetOrdinal("id"));
string password = reader.GetString(reader.GetOrdinal("PassWord"));
Console.WriteLine("id={0},username={1},password={2}",id,username,password);
Console.WriteLine(reader.GetName(2));
}
}
}
}
创建SqldataReader 的实例reader,执行executereader命令,
reader.Read()方法返回值bool类型,依次读取结果集中的每一行,如果有对应的值则返回true,没有则返回false,可调用该方法来依次读取数据。
GetString() 方法,根据列的序号,返回该列字符串形式的值
GetOrdinal() 方法,根据列的列名,得到该列的序号。
GetInt32() 将列的序号转化为有效整数值,不加该方法返回的id值都是0。
GetName() 根据序号返回该列的名称。
Close 和Dispose 的区别:
Close 以后还能打开。
Dispose 直接销毁连接,不能再次利用。
Using 在出了作用域以后调用Dispose.
4.Ado.net中五个常用对象
1.Connection 用于与数据库建立连接。
2.Command 用来向数据库发出指令,建立在connection对象之上。
3.DataReader 用于执行多行多列结果集的查询。根据读取精度从服务器获取数据,不会一次性加载到客户端内存中,因此需要保持客户端与服务器的连接。
4.DataSet 将数据一次性读取到客户端内存中,其内有datatable,datarow等对象,建立在DataAdapter对象之上。
//待完成
5.DataAdapter 用于辅助DataSet,DataTable等绑定数据。例如:
//配置连接字符串
private static readonly string connstr = System.Configuration.ConfigurationManager.ConnectionStrings["bin"].ConnectionString;
/// <summary>
/// BindSource 绑定数据方法
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="dgv">绑定数据的控件</param>
public static void BindSource(string sql,DataGridView dgv)
{
//创建对象
SqlDataAdapter adapter = new SqlDataAdapter(sql, connstr);
DataTable table = new DataTable();
//填充数据
adapter.Fill(table);
//绑定数据
dgv.DataSource = table;
}
5.完整的SqlHelper
Sqlhelper是对sqlconnection,sqlcommand和sqldatareader的封装,将三个类的某些方法封装,使用起来更加简单方便。
/// <summary>
/// 增删改查数据库的工具类
/// </summary>
public class SqlHelper
{
//设置链接字符串,每次使用需要在UI项目下的app中设置name为bin的配置字符串
private static readonly string connstr = System.Configuration.ConfigurationManager.ConnectionStrings["bin"].ConnectionString;
/// <summary>
/// ExecuteNonquery 方法
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="type">执行命令类型</param>
/// <param name="sps">参数数组</param>
/// <returns>受影响行数</returns>
public static int ExecuteNonquery(string sql,CommandType type,params SqlParameter [] sps) {
using (SqlConnection conn = new SqlConnection(connstr)) {
using (SqlCommand cmd=new SqlCommand (sql,conn))
{
//设置执行命令类型
cmd.CommandType = type;
if (sps!=null)
{
//添加参数
cmd.Parameters.AddRange(sps);
}
conn.Open();
return cmd.ExecuteNonQuery();
}
}
}
/// <summary>
/// ExecuteNonquery方法重载
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="sps">参数数组</param>
/// <returns></returns>
public static int ExecuteNonquery(string sql, params SqlParameter[] sps) {
//默认情况下执行sql语句,而非存储过程
return ExecuteNonquery(sql, CommandType.Text, sps);
}
/// <summary>
/// ExecuteScalar方法
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="type">执行命令类型</param>
/// <param name="sps">参数数组</param>
/// <returns>一行一列object类型</returns>
public static object ExecuteScalar(string sql, CommandType type, params SqlParameter[] sps) {
using (SqlConnection conn = new SqlConnection(connstr))
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
//设置执行命令类型
cmd.CommandType = type;
if (sps != null)
{
//添加参数
cmd.Parameters.AddRange(sps);
}
conn.Open();
return cmd.ExecuteScalar();
}
}
}
/// <summary>
/// ExecuteScalar方法重载
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="sps">参数数组</param>
/// <returns>一行一列object类型</returns>
public static object ExecuteScalar(string sql, params SqlParameter[] sps) {
return ExecuteScalar(sql, CommandType.Text, sps);
}
/// <summary>
/// ExecuteReader方法
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="type">执行命令类型</param>
/// <param name="sps">参数数组</param>
/// <returns>SqlDataReader对象</returns>
public static SqlDataReader ExecuteReader(string sql, CommandType type, params SqlParameter[] sps) {
//保持连接
SqlConnection conn = new SqlConnection(connstr);
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
//设置执行命令类型
cmd.CommandType = type;
if (sps != null)
{
//添加参数
cmd.Parameters.AddRange(sps);
}
conn.Open();
//参数确定datareader对象关闭时connection对象连接关闭
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
}
/// <summary>
/// ExecuteReader 方法重载
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="sps">参数数组</param>
/// <returns>sqldatareader对象</returns>
public static SqlDataReader ExecuteReader(string sql, params SqlParameter[] sps) {
return ExecuteReader(sql, CommandType.Text, sps);
}
6.解决sql注入漏洞的方法
1.使用带参数的sql语句
2.使用存储过程
7.MD5Hepler
public class MD5Helper
{
/// <summary>
/// GetPwdMD5 加密字符串(多为密码)的方法
/// </summary>
/// <param name="pwd">字符串</param>
/// <returns>字符串</returns>
public static string GetPwdMD5(string pwd) {
StringBuilder sb = new StringBuilder();
//创建MD5对象
MD5 md5 = MD5.Create();
byte[] bytes = Encoding.Default.GetBytes(pwd);
//计算字节数组的哈希值
bytes= md5.ComputeHash(bytes);
//按格式转换为字符串
for (int i = 0; i < bytes.Length; i++)
{
sb.Append(bytes[i].ToString("x2"));
}
return sb.ToString();
}
public static string GetFileMD5(string path)
{
StringBuilder sb = new StringBuilder();
MD5 md5 = MD5.Create();
//根据路径打开流
using (FileStream fs=File.OpenRead(path) )
{
//转换为byte数组
byte[] bytes = md5.ComputeHash(fs);
for (int i = 0; i < bytes.Length; i++)
{
sb.Append(bytes[i].ToString("x2"));
}
return sb.ToString();
}
}
}