数据访问层的使用方法

一、操作语句部分

 

简单的说就是传入一个操作语句,然后接收返回值就可以了。为了简化代码和提高效率,所以呢设置了五种返回类型。

 

 

 

1 DataSet

 

函数名称:DateSet ds = RunSqlDataSet(查询语句)

 

传入一个查询语句(多条select 的查询语句),然后接收返回值就可以了。

 

没有记录返回 null

 

2 DataTable

 

函数名称:DateTable dt = RunSqlDataTable(查询语句)

 

传入一个查询语句(一条select 的查询语句),然后接收返回值就可以了。

 

没有记录返回 null

 

3 DataRow

 

函数名称:DataRow dr = RunSqlDataRow(查询语句)

 

传入一个查询语句(一条select 的查询语句),然后接收返回值就可以了。

 

没有记录返回 null

 

4 String[]

 

函数名称:string[] str = RunSqlStrings (查询语句)

 

传入一个查询语句(一条select 的查询语句),然后接收返回值就可以了。

 

没有记录返回 null

 

5 String

 

函数名称:string str = RunSqlGetID (查询语句)

 

传入一个查询语句(一条select 的查询语句),然后接收返回值就可以了。

 

没有记录返回 null

 

6 Null

 

函数名称:RunSql (操作语句)

 

传入一个操作语句(insert updatedelete的操作语句)。

 

说明:参数都是字符串型的。

 

 

 

二、存储过程部分

 

简单的说就是和查询语句的很类似了,只不过多了个存储过程的参数。

 

1 DataSet

 

函数名称:DateSet ds = RunStoreDataSet(存储过程的名称)

 

传入存储过程的名称,然后接收返回值。

 

没有记录返回 null

 

2 DataTable

 

函数名称:DateTable dt = RunStoreDataTable(存储过程的名称)

 

传入存储过程的名称,然后接收返回值。

 

没有记录返回 null

 

3 Null

 

函数名称:RunStore (存储过程的名称)

 

传入存储过程的名称。

 

 

 

三、存储过程的参数(1

 

如果没有参数的话,那么存储过程的用法和查询语句的也就一样了。但是呢,大多数的存储过程都是有参数的,不过有了参数我们也不怕!

 

我们可以用addNewParameter方法来添加存储过程的参数。不用像SQLHelp那样麻烦,还得传入一个Parameter的对象。我们直接调用数据访问层的方法就可以了。

 

这里通过函数重载的方式来区分不同的数据类型。以C#里的数据类型为标准,对应SQL里面的数据类型。

 

1 int型的参数

 

这里对应三个SQL Server的数据类型:inttinyintsmallint

 

函数名称:addNewParameter(string ParameterName,int ParameterValue)

 

ParameterName:参数名称。

 

ParameterValue:参数值。

 

 

 

2 bit型的参数

 

这里对应一个SQL Server的数据类型:bit

 

函数名称:addNewParameter(string ParameterName,bool ParameterValue)

 

ParameterName:参数名称。

 

ParameterValue:参数值。

 

3 double型的参数

 

这里对应两个SQL Server的数据类型:floatreal

 

函数名称:addNewParameter(string ParameterName,double ParameterValue )

 

ParameterName:参数名称。

 

ParameterValue:参数值。

 

4 string型的参数

 

这里对应七个SQL Server的数据类型:charncharvarcharnvarcharuniqueidentifiersmalldatetimedatetime

 

函数名称:addNewParameter(string ParameterName,string ParameterValue,int size)

 

ParameterName:参数名称。

 

ParameterValue:参数值。

 

Size   参数的大小。

 

5 ntext型的参数

 

这里对应两个SQL Server的数据类型:ntexttext

 

函数名称:addNewParameter(string ParameterName,string ParameterValue)

 

ParameterName:参数名称。

 

ParameterValue:参数值。

 

6 金额型的参数

 

这里对应三个SQL Server的数据类型:decimalsmallmoneymoney

 

函数名称:addNewParameter(string ParameterName,decimal ParameterValue)

 

ParameterName:参数名称。

 

ParameterValue:参数值。

 

7 说明

 

还有二进制类型的没有处理。忘记要用C#的哪个类型来对应了。

 

这里添加的参数都是输入型(input)的,如果想设置输出型的参数请看下面。

 

四、存储过程的参数(2

 

这里讲述如何设置输出型(output)的参数,以及如何修改参数值、取值和清除参数

 

1 设置输出型参数

 

函数名称:addNewParameter(string ParameterName,ZDIC.ParameterKind kind)

 

ParameterName:参数名称。

 

Kind:参数类型。

 

2 获取参数的返回值

 

函数1名称:getParameter(int ParameterIndex)

 

ParameterIndex:参数的序号。

 

通过参数的序号来返回参数值。

 

 

 

函数2名称:getParameter(string ParameterName)

 

ParameterName:参数的名称。

 

      通过参数名称来返回参数值。

 

 

 

3 修改参数值

 

函数1名称:setParameter(int ParameterIndex,string parameterValue)

 

ParameterIndex:参数的序号。

 

通过参数的序号来修改参数值。

 

 

 

函数2名称:setParameter(string ParameterName,string parameterValue)

 

ParameterName:参数的名称。

 

通过参数名称来修改参数值。

 

 

 

4 清除参数

 

函数名称:ClearParameter()

 

执行一下就行除了。

 

 

 

五、异常处理

 

这里并不向上层抛出异常,取代的是给ErrorMsg属性赋值。如果程序正常执行,则ErrorMsg==0表示没有发生异常;否则ErrorMsg的内容就是错误描述。

 

错误描述包括三个部分:函数名称,执行的查询语句(存储过程)和系统给出的错误信息。这样呢就很容易发现出错的地方,尤其是在使用查询语句的时候。

 

 

 

六、错误日志

 

在发生异常的时候,会自动记录错误信息,以便日后的维护和修改错误。

 

错误日志以文本文件的形式存放在 /log文件夹下面,文件名是yyyyMMdd的格式。

 

为什么用文本文件而不用数据库?因为一般在正式使用后发生的异常大多都是由于数据库造成的,所以很有可能在发生异常之后已经无法再向数据库里写信息了。而向文本文件里写信息一般是不会出错的。

 

 

 

七、连接字符串及Connection对象

 

连接字符串是从 Connection.dll 里面读取的,其目的是适应连接字符串的各种变化。比如是否加密,用什么算法加密;连接字符串存放在什么地方?web.configDLL、注册表或者其他的什么地方。引用Conection.dll后就可以很轻松的应对以上的这些要求。

 

 

 

八、事务处理

 

利用 Connection.BeginTransaction 等方法实现事务。没有作严格的测试,因为目前还没有用到。

 

 

 

九、更换数据库

 

这里是针对SQL Server 数据库做的处理,也就是对SqlClinet进行的封装。如果更换数据库的话,那么只需要把Sql字样换成对应的数据库的表示就可以了。其他的作一些适当的调整就可以了。

 

 

 

十、使用示例

 

以新闻系统为例

 

1 用查询语句的方式获取新闻列表,然后绑定Repeater控件。

 

DataAccessLayer dal = new DataAccessLayer();

 

Rpt.DataSource = dal.RunSqlDataTable("select NewsID,addedDate,title from news ");

 

if (dal.ErrorMsg.Length > 2 )

 

{

 

 Response.Write(dal.ErrorMsg ); //输出错误信息

 

 return;

 

}

 

Rpt.DataBind();

 

 

 

2 用存储过程的方式获取新闻列表,然后绑定Repeater控件。

 

DataAccessLayer dal = new DataAccessLayer();

 

Rpt.DataSource = dal.RunStoreDataTable("Proc_News_list");

 

if (dal.ErrorMsg.Length > 2 )

 

{

 

 Response.Write(dal.ErrorMsg ); //输出错误信息

 

 return;

 

}

 

Rpt.DataBind();

 

 

 

3 string[]的方式获取一条新闻纪录。然后给Label控件赋值。

 

DataAccessLayer dal = new DataAccessLayer();

 

string sql = "select Title,AddedDate,Content from News where NewsID=" + NewsID

 

string[] Infos = dal.RunSqlStrings(sql);

 

if (dal.ErrorMsg.Length > 2 )

 

{

 

 Response.Write(dal.ErrorMsg ); //输出错误信息

 

 return;

 

}

 

if (Infos == null)

 

{

 

 Response.Write("没有这条新闻!");

 

 Response.End();

 

}

 

 Lbl_Title.Text = Infos[0];

 

 Lbl_AddedDate.Text = Infos[1].Split(' ')[0];

 

 Lbl_Content.Text = Infos[2];

 

 

 

4 DataRow的方式获取一条新闻纪录。然后给Label控件赋值。

 

DataAccessLayer dal = new DataAccessLayer();

 

string sql = "select Title,AddedDate,Content from News where NewsID=" + NewsID

 

DataRow Infos = dal.RunSqlDataRow(sql);

 

if (dal.ErrorMsg.Length > 2 )

 

{

 

 Response.Write(dal.ErrorMsg ); //输出错误信息

 

 return;

 

}

 

if (Infos == null)

 

{

 

 Response.Write("没有这条新闻!");

 

 Response.End();

 

}

 

 Lbl_Title.Text = Infos["Title"].ToString();

 

 Lbl_AddedDate.Text = Infos["AddedDate"] .ToString().Split(' ')[0];

 

 Lbl_Content.Text = Infos["Content"] .ToString();

 

 

 

5 InsertDataStrUpdateData实现添加、修改新闻。同时用RunSqlExists判断新闻标题是否重复。

 

//判断是修改还是添加

 

bool isAdd = false;

 

if (DG.SelectedIndex == -1) //利用DataGrid的状态来判断是添加还是修改。

 

     isAdd = true;

 

 

 

//设定字段。这里一定要用一个数组来表示,这是 InsertDataStr 函数的参数的要求!

 

string[] str1 = new string[2];

 

str1[0] = "title";

 

str1[1] = "Content";

 

 

 

//获取用户输入的信息,并且过滤危险字符

 

//这里一定要用一个数组来表示,这是 InsertDataStr 函数的参数的要求!

 

string[] str = new string[2];

 

str[0] = this.Txt_Title.Text.Trim().Replace("'","");

 

str[1] = this.Txt_Content.Text.Trim().Replace("'","");

 

#region 数据验证

 

if (str[0].Length == 0 )

 

{

 

 Page.RegisterStartupScript("a",Functions.myAlert("请填写新闻标题!"));

 

 return;

 

}

 

 

 

DataAccessLayer dal = new DataAccessLayer();

 

if (isAdd)

 

{

 

     if (dal.RunSqlExists("select top 1 '1' from news where title='" + str[0] + "'" ))

 

     {

 

      Page.RegisterStartupScript("a",Functions.myAlert("已经有这个新闻标题了!"));

 

      return;

 

     }

 

}

 

else

 

{

 

     if (dal.RunSqlExists("select top 1 '1' from news where title='" + str[0] + "' and NewsID <>" + DG.SelectedItem.Cells[0].Text))

 

     {

 

      Page.RegisterStartupScript("a",Functions.myAlert("已经有这个新闻标题了!"));

 

      return;

 

     }

 

}

 

#endregion

 

if (isAdd)

 

     //添加新闻

 

 dal.InsertDataStr("News",str1,str);

 

else

 

     //修改新闻

 

 dal.UpdateData("News",str1,str," NewsID=" + DG.SelectedItem.Cells[0].Text);

 

 

 

//检查是否出现异常

 

if (dal.ErrorMsg.Length > 2 )

 

{

 

 Response.Write(dal.ErrorMsg );  //输出错误信息

 

 return;

 

}

 

if (isAdd)

 

     //添加成功。进行相应处理

 

else

 

     //修改成功。进行相应处理

 

 

 

6 RunStore 用的方式添加修改新闻

 

//判断是修改还是添加

 

bool isAdd = false;

 

if (DG.SelectedIndex == -1) //利用DataGrid的状态来判断是添加还是修改。

 

     isAdd = true;

 

 

 

//获取用户输入的信息,存储过程的方式就不用过滤了

 

string NewsTitle = this.Txt_Title.Text.Trim();

 

string NewsContent = this.Txt_Content.Text;

 

 

 

// 数据验证

 

if (str[0].Length == 0 )

 

{

 

 Page.RegisterStartupScript("a",Functions.myAlert("请填写新闻标题!"));

 

 return;

 

}

 

//标题是否重复的判断由存储过程来实现

 

 

 

DataAccessLayer dal = new DataAccessLayer();

 

//添加存储过程的参数

 

dal.addNewParameter("@title",NewsTitle,100);

 

dal.addNewParameter("@Content",NewsContent);

 

//output型的参数

 

dal.addNewParameter("@ReturnMsg",ParameterKind.NVarChar );

 

 

 

if (!isAdd)

 

     //修改新闻,需要给 @NewsID 负值。

 

    dal.addNewParameter("@NewsID",Int32.Parse(DG.SelectedItem.Cells[0].Text))

 

 

 

//执行存储过程

 

dal.RunStore("Proc_News_ModData");

 

 

 

//检查是否出现异常

 

if (dal.ErrorMsg.Length > 2 )

 

{

 

 Response.Write(dal.ErrorMsg );  //输出错误信息

 

 return;

 

}

 

string err = dal.getParameter("@ReturnMsg");//获取参数的返回值

 

if (isAdd)

 

{//添加状态

 

     if (err.Length > 1)

 

     {

 

      //显示存储过程里面返回的错误信息,比如新闻标题重名等。

 

     }

 

     else

 

     {

 

      //添加成功

 

      SetFormEmpty();

 

     }

 

}   

 

else

 

{//修改状态

 

     if (err.Length > 1)

 

     {

 

      //显示存储过程里面返回的错误信息,比如新闻标题重名等。

 

     }

 

     else

 

     {

 

      //修改成功

 

      SetFormVisible(false);

 

     }

 

}

 

 

 

7 RunSql 删除新闻

 

DataAccessLayer dal = new DataAccessLayer();

 

dal.RunSql("delete from News where NewsID=" + e.Item.Cells[0].Text);

 

//检查是否出现异常

 

if (dal.ErrorMsg.Length > 2 )

 

{

 

 Response.Write(dal.ErrorMsg ); //输出错误信息

 

 return;

 

}

 

 

 

8 说明

 

除了添加修改的地方,代码都是非常简洁的。可以说只用了一行就达到了目的。由于省去了实体层,数据访问层也变成了DLL类库,所以说呢,从表面上看程序的结构就变成了一层结构了,也就是说只需写这些代码就可以实现一个模块的基本功能了。

 

再来看看添加修改的地方。虽然代码好像多了一点,但是合并了添加、修改的共同的地方,减少了三分之一的代码。可能会比三层结构的UI层的代码量多一些,但是没有实体层、业务逻辑层和数据访问层的代码。重整体上来说减少了三倍的代码量。

 

修改上也是很方便的。如果要修改字段名称的话,只需要修改str1数组里对应的值就可以了;添加字段呢,只需要增加str1str数组的大小,并负值就可以了。省去了其他层的修改(因为根本就没有在其他的地方写代码!)

 

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值