要注意DataSet的写法,有点麻烦
SqlHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
namespace WPFDemo01
{
class SqlHelper
{
//基础版SqlHelper
////注意,要用这行代码前提是将连接字符串配置在了app.config配置文件中
//private static string connstr = ConfigurationManager.ConnectionStrings["linkDBStr"].ConnectionString;
////封装方法的原则:把不变的放到方法里,把变化的放到参数中。
////注意,命名虽然可以随便,但是要写好意思方便阅读
////执行Update,Delete,Insert语句
//public static int ExecuteNonQuery(string sql)
//{
// using (SqlConnection conn = new SqlConnection(connstr))
// {
// conn.Open();
// using (SqlCommand cmd = conn.CreateCommand())
// {
// cmd.CommandText = sql;
// return cmd.ExecuteNonQuery();
// }
// }
//}
////返回第一行第一列
//public static object ExecuteScalar(string sql)
//{
// using (SqlConnection conn = new SqlConnection(connstr))
// {
// conn.Open();
// using (SqlCommand cmd = conn.CreateCommand())
// {
// cmd.CommandText = sql;
// return cmd.ExecuteScalar();
// }
// }
//}
//DataSet版本1
////返回一个DataSet,这里因为一般只会返回一个table,
////所以返回值改为datatable更为简便,
////以后根据需要看着改变
////注意:只用来执行查询结果比较少的sql
//public static DataTable ExecuteDataTable(string sql)
//{
// using (SqlConnection conn = new SqlConnection(connstr))
// {
// conn.Open();
// using (SqlCommand cmd = conn.CreateCommand())
// {
// cmd.CommandText = sql;
// SqlDataAdapter adapter = new SqlDataAdapter(cmd);
// DataSet dataset = new DataSet();
// adapter.Fill(dataset);//把adapter放入dataset中
// return dataset.Tables[0];
// }
// }
//}
//注意,要用这行代码前提是将连接字符串配置在了app.config配置文件中
private static string connstr = ConfigurationManager.ConnectionStrings["linkDBStr"].ConnectionString;
//封装方法的原则:把不变的放到方法里,把变化的放到参数中。
//注意,命名虽然可以随便,但是要写好意思方便阅读
//执行Update,Delete,Insert语句
public static int ExecuteNonQuery(string sql,SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connstr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
//foreach (SqlParameter param in parameters)
//{
// cmd.Parameters.Add(param);
//}
cmd.Parameters.AddRange(parameters);//实质和foreach是一样的
return cmd.ExecuteNonQuery();
}
}
}
//返回第一行第一列
public static object ExecuteScalar(string sql,SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connstr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
return cmd.ExecuteScalar();
}
}
}
////DataSet版本2
////返回一个DataSet,这里因为一般只会返回一个table,
////所以返回值改为datatable更为简便,
////以后根据需要看着改变
////注意:只用来执行查询结果比较少的sql
//public static DataTable ExecuteDataTable(string sql, SqlParameter[] parameters)
//{
// using (SqlConnection conn = new SqlConnection(connstr))
// {
// conn.Open();
// using (SqlCommand cmd = conn.CreateCommand())
// {
// cmd.CommandText = sql;
// cmd.Parameters.AddRange(parameters);
// SqlDataAdapter adapter = new SqlDataAdapter(cmd);
// DataSet dataset = new DataSet();
// adapter.Fill(dataset);//把adapter放入dataset中
// return dataset.Tables[0];
// }
// }
//}
//DataSet版本3:使用长度可变参数来简化
//注意:长度可变参数必须是数组类型
public static DataTable ExecuteDataTable(string sql,params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connstr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet dataset = new DataSet();
adapter.Fill(dataset);//把adapter放入dataset中
return dataset.Tables[0];
}
}
}
}
}
WPF代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
namespace WPFDemo01
{
/// <summary>
/// ADOBasic.xaml 的交互逻辑
/// </summary>
public partial class ADOBasic : Window
{
public ADOBasic()
{
InitializeComponent();
}
private void btnLink_Click(object sender, RoutedEventArgs e)
{
//对实现了IDisposible接口的,使用using关键字,它能控制对资源的释放,具体的自行百度。语法是
//using(类型d = new (这里面指的是创建对象)......){.................}他可以自动回收资源,不用自己关闭数据库
//以后都这么写,conn.close();的方法前面程序挂掉了,那么数据库就没有关,这样时间久了会造成数据库泄露
//SqlConnection建立和数据库的连接
//1.第一种,
//ExecuteNonQuery()通常用来执行Update,Delete,Insert语句,就如单词所示NonQuery,非查询!
//using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
//{
// conn.Open();
// MessageBox.Show("数据库连接成功!");
// //通过连接创建一个向数据库发命令(command)的对象
// using(SqlCommand cmd = conn.CreateCommand())
// {
// //CommandText为要执行的sql语句
// cmd.CommandText = "insert into T_Students(id,name,age,aihao,height) values (101,'刘亦菲',23,'北京吧',170);";
// cmd.ExecuteNonQuery(); //开始执行
// }
//}
//2.第二种,
//查询用ExecuteScalar()返回的是一行一列的值
//using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
//{
// conn.Open();
// using(SqlCommand cmd = conn.CreateCommand())
// {
// //例1:
// //cmd.CommandText="select count(*) from T_Students";
// //ExecuteScalar()返回的是一行一列的值使用该类型,意思就是查询的结果只有一个,
// //因为其返回的是object类型,所以根据我们返回的实际类型可以进行强制类型转换,
// //这里一定要写对对应类型,比如数据库中的varchar类型对应C#中的是string,
// //bigint类型对应的是long类型
// //int i =(int)cmd.ExecuteScalar();
// //MessageBox.Show("查询到结果数为:"+i+"条");
// //例2:
// //cmd.CommandText = "select 'dafa'";
// //string s = (string)cmd.ExecuteScalar();
// //MessageBox.Show(s);
// //例3:
// //本数据库中自增长字段为addId,其值是数据库自动分配的,
// //那么我们如何得知本数据的addId是多少呢?
// cmd.CommandText = "insert into T_Students(id,name,age,aihao,height) output inserted.addId values (10000,'离死',102,'',80)";
// int i = (int)cmd.ExecuteScalar();
// MessageBox.Show("当前addId为:"+i);
// }
//}
//3.第三种,
//执行有多行结果的结果集用ExecuteReader,同样是实现IDisposible接口的
//SqlDataReader reader = cmd.ExecuteReader();.....
//while(reader.Reader())
//{
//Console.writeLine(reader.GetString(1));
//}这里要和注意,该查询结果是放在数据库中的,没有放到
//客户端,初始指针指向第一条数据之前,每调用一次Reader指针
//下移一条,只要没有移到最后一条之后,就一直返回true
//reader的GetString、GetInt32的方法只接受整数参数,
//也就是序号,用GetOrdinal方法根据列名动态得到序号
using(SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Students;";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
string name = reader.GetString(1); //根据数据库返回值类型写C#对应类型,这里面的参数表示返回该行的第几列
int age = reader.GetInt32(2); //这里的类型对应有点麻烦,要注意
MessageBox.Show("名字是:"+name+" "+"年龄是:"+age);
}
}
}
}
MessageBox.Show("执行完成~!");
}
private void btnSearch_Click(object sender, RoutedEventArgs e)
{
using(SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
//此字符串拼接方法,如果这里输入“1' or '1'='1”,则会查出所有的结果,造成了SQL注入漏洞
//cmd.CommandText = "select * from T_Students where name = '"+txtPerson.Text+"'";
//@Name是占位符,表示我这里需要一个Name的值,这样看起来更有意义,但是name这个词可以换成其他的任意词
cmd.CommandText = "select * from T_Students where Name=@Name or Age=@Age";
//用法1:
//cmd.Parameters.AddWithValue("@Name",txtPerson.Text);
//用法2:推荐使用
cmd.Parameters.Add(new SqlParameter("@Name",txtPerson.Text));
//注意如果是别的类型的注意转换类型
cmd.Parameters.Add(new SqlParameter("@Age", Convert.ToInt32(txtPerson.Text)));
//此语句也可以用在如下语句等
//insert into......values(@Name,@Age...)
//delete ...... where ID=@idAdd
//注意"@参数"不能用在替换表名、字段名、select之类的关键字等。
//如下都是不可以的!
//select age from @TableName..
//select @AgeName from table...
using(SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
//GetInt32获得的是int类型
//GetInt64获得的是long类型(数据库中是bigint)
int id = reader.GetInt32(0);
string name = reader.GetString(1);
int age = reader.GetInt32(2);
string address = reader.GetString(3);
int addId = reader.GetInt32(4);
MessageBox.Show(id.ToString()+" "+name+" "+age.ToString()+" "+address+" "+addId.ToString());
}
}
}
}
}
//4.第四种
//SqlDataReader是连接相关的,SqlDataReader中的查询结果并不是放到程序中,
//而是放在数据库服务器中,SqlDataReader只是相当于放了一个指针(游标),只能
//读取当前游标指向的行,一旦连接断开就不能再读取。这样做的好处就是无论查询
//结果有多少条,对程序占用的内存都几乎没有影响。
//SqlDataReader对于小数据量的数据来说带来的只有麻烦。ado.net中提供了数据集的
//机制,将查询结果填充到本地内存中,这样连接断开、服务器断开都不影响数据的读取。
//数据集的好处就是降低数据库服务器压力,编程也简单。
//DataSet dataset = new DataSet();
//SqlDataAdapter adapter = new SqlDataAdapter(cmd);
//adapter.Fill(dataset);
//DataSet包含若干表DataTable,DataTable包含若干行DataRow,
private void btnDataSet_Click(object sender, RoutedEventArgs e)
{
using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Students where age<@Age";
cmd.Parameters.Add(new SqlParameter("@Age",txtAge.Text));
//SqlDataAdapter是一个帮我们把SqlCommand查询的结果
//填充到DataSet中的一个类
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
//DataSet相当于本地的一个复杂集合(类似于List<int>)
DataSet dataset = new DataSet();
//执行cmd并且把SqlCommand查询的结果填充到DataSet
adapter.Fill(dataset);
//dataset可以放多个表,我们只放了一个表,所以下标为0
DataTable table = dataset.Tables[0];
//得到表中有多少行
DataRowCollection rows = table.Rows;
for (int i = 0; i < rows.Count; i++ )
{
//取出多行中的第i行
DataRow row = rows[i];
//分别去除第i行中的各个列的值
int age = (int)row["Age"];
string name = (string)row["Name"];
MessageBox.Show(name + ","+age);
}
}
}
}
//5.第五,连接字符串配置
//(1)新建项目,应用程序配置文件,App.config,名字必须是这样
// <configuration>
// <connectionStrings>
// <add name="英文名随意" connectionString="数据库连接字符串"/>
// </connectionStrings>
// </configuration>
// (2)然后项目要引用一个类,该类位于.Net-->System.Configuration,
// 代码中:
// string connstr = ConfigurationManager.ConnectionStrings["linkDBStr"].ConnectionString;
private void btnConfig_Click(object sender, RoutedEventArgs e)
{
string connstr = ConfigurationManager.ConnectionStrings["linkDBStr"].ConnectionString;
MessageBox.Show(connstr);
}
//6.第六。这里使用了自定义的SqlHelper类。
private void btnSqlHelper_Click(object sender, RoutedEventArgs e)
{
//不用长度可变参数的话,调用起来麻烦
//SqlHelper.ExecuteNonQuery("insert into T_Students(id,name,age,address) values(22,'账期',21,'北京')");
//DataTable table = SqlHelper.ExecuteDataTable("select * from T_Students where age<80");
//DataTable table = SqlHelper.ExecuteDataTable("select * from T_Students where age<@Age",
// new SqlParameter[]{new SqlParameter("@Age",500)});
DataTable table = SqlHelper.ExecuteDataTable("select * from T_Students where age<@Age or name=@Name",
new SqlParameter("@Age", 500), new SqlParameter("@Name", "小天"));
foreach(DataRow row in table.Rows)
{
string name = (string)row["Name"];
MessageBox.Show(name);
}
}
}
}