黑马程序员_学习日记48_616数据库开发及ADO.Net(带参数的Sql语句、数据库与文本文件导入导出、省市联动、资料管理器、DataSet (ado.net断开式数据访问)、SQLHelper)

一、带参数的Sql语句(避免注入攻击)

(一)   注入漏洞攻击

在用户名中输入:jk’ or 1=1 --

select count(*) from UserLogin where loginId=’jk’ or 1=1 --‘ and Loginpwd=’jk1324657’

 

(二)   带参数的Sql语句

--@uid不用单引号引起来

string sql = “select count(*) from UserLogin where LoginId=@uid and LoginPwd=@pwd”;

using(SqlCommand cmd = new SqlCommand(sql,con))

{

         cmd.Parameters.AddWithValue(“@uid”,txtUid.Text.Trim()uidParameters.AddWithValue()nd()d and LoginPwd=@pwdId);

         cmd.Parameters.AddWithValue(“@pwd”,txtPwd.Text uidParameters.AddWithValue()nd()d and LoginPwd=@pwdId);

}

在数据库中,两个’’表示一个

 

二、数据库与文本文件导入导出

(一)   数据库导出到文件

//需要创建一个写入文件的文件流StreamWriter

using(StreamWriter sw = new StreamWriter(@”tblclass.txt”))

{

         while(reader.Read())

         {

         object objClsId = reader.GetValue(0);

         object objClsName = reader.GetValue(1);

         object objClsDesc = reader.GetValue(2);

         string line = string.Format(“{0},{1},{2}”, objClsId, objClsName, objClsDesc);

         sw.WriteLine(line);

}

}

(二)   文件导入到数据库

防止参数重名:

1、  方法一:

while(!sr.EndOfStream)

{

         string line = sr.ReadLine();

         string[] columns=line.Split(‘,’);

        

         SqlParameter p1 = new SqlParameter(“@clsName”,columns[1]);

SqlParameter p2 = new SqlParameter(“@clsDesc”,columns[2]);

cmd.Parameter.Add(p1);

cmd.Parameter.Add(p2);

cmd.ExecuteNonQuery();

//每次用完参数,将参数集合清空。

cmd.Parameter.Clear();

}

2、  方法二:

SqlParameter p1 = new SqlParameter(“@clsName”,SqlDbType.VarChar);

SqlParameter p2 = new SqlParameter(“@ClsDesc”,SqlDbType.VarChar);

cmd.Parameter.Add(p1);

cmd.Parameter.Add(p2);

 

con.Open();

while(!sr.EndOfStream)

{

         string line = sr.ReadLine();

         string[] columns = line.Split(‘,’);

        

         p1.Value = Columns[1];

         p2.Value = Columns[2];

         cmd.ExecuteNonquery();

}

(三)   省市联动案例

//获取配置文件中的连接字符串

string constr = ConfigurationManager.ConnectionString[0].ConnectionString;

//建议编写实体类的时候用属性,不用字段,因为很多控件不支持字段。

(四)   资料管理器(数据库版)

1//窗体加载事件

Form_Load()

{

         //加载文章类别到treeview

}

 

//实际开发应避免使用DataReader,用List集合

LoadCategoryToTree()

{

         连接字符串

         using(con)

         {

         sql = “select tid,tname from Category where tParentId = -1”;

         …

         categoryId = reader.GetInt32(0);

         categoryName = reader.GetString(1);

         //将当前类别加载到TreeView

         TreeNode tnode = treeview1.Add(categoryName);

         tnode.Tag = categoryId;

        

         //加载当前类(categoryId)下的所有子类

         LoadSubCategory(categoryId,tnode)

}

}

//该方法创建一个新的连接,因为上一个方法的连接还没有关闭。

LoadSubCategory()

{

         …

         TreeNode subTNode = tnode.Nodes.Add(CategoryName);

}

 

//选中类别改变后的事件

treeView1_AfterSelect(object sender,TreeViewEventArgs e)

{

         //e.Node表示当前选中的节点

         if(e.Node.Level == 1)//选中2级节点

         {

             object categoryId = e.Node.Tag;

                   //根据类别IdcategoryId)加载文章到ListBox

LoadContentInfo(categoryId);

                  

}

}

//ListBox中加载文章标题

LoadContentInfo()

{

         listBox1.Items.clear();

         sql = “select did,dname from ContentInfo where dtid = @cateId”;

         …

         listBox1.Items.Add(wz);

}

 

//文章标题选择项改变事件

listBox1_SelectedIndexChanged()

{

         if(listBox1.SelectedItem != null)

         {

         //根据文章Id,查询文章内容

         GetArticleContentById();

}

}

 

GetArticleContentById()

{

         string sql = “select dcontent from ContectInfo where dId=@id”;

cmd.Parameters.AddWithValue()

object objContent = cmd.ExecuteScalar();

return objContent.ToString();

}

 

2、  写配置文件(连接字符串)

<configuration>

         <connectionStrings>

                   <add name=”sql” connectionString=”Data Source=.\SQLEXPRESS”/>

         </connectionStrings>

</configuration>

3、  建立WenZhang

 

三、DataSet  (ado.net断开式数据访问)

DataSet是什么?临时数据集

(一)   自己写DataSet

//1、创建一个临时数据库

DataSet ds = new DataSet(“School”);

//2、创建临时表

DataTable dt = new DataTable(“Student”);

//2.1dt加列

DataColumn dcAutoId = new DataColumn(“autoId”);

dcAutoId.AutoIncrement = true;

dt.Columns.Add(“loginId”);

 

dt.Columns.Add(“loginId”,typeof(string));

dt.Columns[0].Uinque = true; //唯一性

for()

{

22DataTable增加行

//创建DataRow不能new

DataRow dr = dt.NewRow();

dr[1] = “zxh”;

dr[2] = “zxh1234567”;

 

dt.Rows.Add(dr);

}

 

循环遍历输出DataSet

foreach(DataTable)

{

         cw(dtItem.TableName);

         foreach(DataRow)

         {

         for(循环列)

         {

        

}

cwl();

}

}

 

//3、将DataTable加到DataSet

ds.Tables.Add(dt);

(二)   自动填充DataSet

//SqlDataAdapter内部封装了SqlConnectionSqlCommandSqlDataReader

SqlDataAdapter adapter = new SqlDataAdapter(sql,constr);

DataSet ds = new DataSet();

adapter.Fill(ds);

dataGridView1.DataSource = ds.Tables[0];

 

数据多了使用SqlDataAdapter分页

DataTable dt = new DataTable();

adapter.Fill(0,10,dt);

dataGridView1.DataSource =dt;

 

四、SQLHelper

封装一个SQLHelper方便使用

1、  建配置文件

2、   

public static class SqlHelper

{

         //获取配置文件中的连接字符串

         private static readonly string constr =ConfigurationManager.ConnectionStrings[“sql”].ConnectionString;

         //封装ExecuteNonQuery

public static int ExecuteNonQuery(string sql,params SqlParameter[] pms)

{

         using(SqlConnection con = new SqlConnection(constr))

         {

         using(SqlCommand cmd = new SqlCommand(sql,con))

         {

         //如果pmsnull,则直接调用cmd.Parameters.AddRange(pms)会报错

         if(pms!=null)

         {

         cmd.Parameters.AddRange(pms);

}

con.Open();

return cmd.ExecuteNonquery();

}

}

}

 

//封装ExecuteScalar

 

//封装ExecuteReader

//注意

1、  Connection不能关闭

2、  DataReader不能关闭

3、  command对象执行ExecuteReader()的时候需要传递一个参数

public static SqlDataReader ExecuteReader(string sql,params SqlParameter[] pms)

{

         SqlConnection con = new SqlConnection(constr);

         using(SqlCommand cmd = new SqlCommand(sql,con))

         {

if(pms!=null)

{

         cmd.Parameters.AddRange(pms);

}

con.Open();

//当调用ExecuteReader()方法的时候,如果传递一个CommandBehavior.CloseConnecton参数,则表示将来当用户关闭reader的时候,系统会自动将Connection也关闭掉

SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);

return reader;

}

}

 

//封装一个返回DataTable的方法ExecuteDataTable()

}

以后在ADO.Net中检索数据库中的数据用:

App.comfig+SqlHelper+带参数的SQL语句

这里的参数的声明方法:

//这里不能用cmd.Parameter.Add()

            SqlParameter[] pams = new SqlParameter[]{

                new SqlParameter("@UserName",txtUserName),

                new SqlParameter("@Password",txtPassword)

            };

 

连接池可以在连接字符串中打开关闭

 

作业:P65登录错三次禁止

P67 练习

资源管理器(数据库版)右键增加子类别,删除类别

将类别导出到记事本

将记事本文件导入到当前类别下

CSV电话本

 

我的作业:

怎么用List集合取代DataSet

treeview搞懂!

 

问题:什么是存储过程?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值