其实添加数据也可以这样简单——表单的第一步抽象(针对数据访问层)《怪怪设计论: 抽象无处不在 》有感
2007-09-18 21:36
387 查看
[b]更正:
[/b]不好意思,昨天晚上思路有点混乱。有几个前提忘记说明了,现在补充一下。
1、缩小范围。按照由简到难的思路,这里先讨论最简单的添加数据的情况。就是单表的添加和修改;这里讨论的是webform的情况。
2、第一步抽象是针对数据访问层的抽象。
如果我没有理解错的话,现在大多数人的做法是:有一个表(或者几个有关联的表)在数据层里就要有一个“函数”与之对应,
如果采用的是SQL语句的方式的话,那么函数的内筒就是组合SQL语句的代码,
如果采用的是存储过程的方式的话,那么函数的内筒就是给存储过程的参数赋值。
而我这里只需要一个函数就可以了。这个函数是共用的,是针对所有表的。再准确点说:SQL语句对应两个函数(一个添加数据、一个修改数据),存储过程对应一个函数(是添加还是修改在存储过程内部判断)。存储过程的方式在这里没有说明。
3、在这里的代码我想写的尽量简单,写多了就会影响主体,所以这里只写了主要代码。
4、如果您有时间的话,您可以拿我的这段代码(实现添加修改数据功能)和您自己写的类似的功能的代码对应一下,先看一下代码量,然后再看一下如果要增加字段(比如加一个新闻字数),需要修改的代码的数量。
5、第二步抽象是针对后置代码的,也可以叫做逻辑层吧。第三步抽象是针对UI的。
和Artech的思路有些类似。我是想从基础的代码一步一步写上去,我要是直接写我现使用的方式,估计大家不太容易看懂。
6、我的思路是:用简单的代码实现复杂的功能(客户的要求)!
7、怪怪设计论: 抽象无处不在
为了便于说明,先举个实际的例子吧。比如要实现一个发布信息(比如新闻)的功能,说白了就是添加数据。
我的做法是先设计数据库,然后写.aspx (UI),然后写.aspx.cs(后置代码),然后就完成了。
设计数据库:表名叫做 news ,有一下几个字段
NewsAdd.aspx 添加数据的页面(UI)
<form id="Form1" method="post" runat="server">
<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="400" align="center" border="1">
<TR>
<TD align="right">标题:</TD>
<TD>
<hbs:HBSTextBox id="Txt_Title" runat="server" Columns="50"></hbs:HBSTextBox></TD>
</TR>
<TR>
<TD align="right">类别:</TD>
<TD>
<hbs:HBSDropDownList id="Lst_Kind" runat="server" Width="112px"></hbs:HBSDropDownList></TD>
</TR>
<TR>
<TD align="right">作者:</TD>
<TD>
<hbs:HBSTextBox id="Txt_Editor" runat="server" Columns="50"></hbs:HBSTextBox></TD>
</TR>
<TR>
<TD align="right">内容:</TD>
<TD>
<hbs:HBSTextBox id="Txt_Content" runat="server" TextMode="MultiLine" Rows="5" Columns="50"></hbs:HBSTextBox></TD>
</TR>
</TABLE>
<hr color="#39689f">
<TABLE cellSpacing="1" cellPadding="1" width="100%" align="center" border="0">
<TR>
<TD align="center">
<asp:Button id="Btn_Save" runat="server" Width="70px" Text=" 确 定 "></asp:Button> <INPUT id="Btn_Return" type="button" value=" 返 回 " onclick="myEsc()"></TD>
</TD></TR>
</TABLE>
</form>
可以暂时把 hbs:HBSTextBox 当作一般的 TextBox 看待,HBSTextBox 是我继承了TextBox写的一个自定义服务器控件。
后置代码(可以看作逻辑层吧)
private void Page_Load(object sender, System.EventArgs e)
#region 查询语句的方式添加、修改数据
/// <summary>
/// 添加记录。传入表名,字段数组,值数组,返回新生成记录的ID
/// </summary>
/// <param name="TableName">要添加记录的表的名称</param>
/// <param name="ziduan">字段名数组</param>
/// <param name="msg">字段对应的值的数组</param>
/// <returns></returns>
public string InsertDataStr(string TableName , string[] ziduan , string[] msg )
/// <summary>
/// 修改记录。传入表名,字段数组,值数组
/// </summary>
/// <param name="TableName">要修改记录的表的名称</param>
/// <param name="ziduan">字段名数组</param>
/// <param name="msg">字段对应的值的数组</param>
/// <param name="tiaojian">条件 ,加在where 后面的语句</param>
/// <returns></returns>
public bool UpdateData( string TableName ,string[] ziduan ,string[] msg ,string tiaojian)
#endregion
思路呢就是 组合成 insert into 的SQL语句,insert 需要什么信息呢?表名,字段名和字段对应的值。
我把这三个信息用一个字符串和两个数组传递进来,然后用两个for 循环来组合。最后通过 ADO.net 提交给数据库执行。
这样99%以上的表的添加都可以用这个函数了,是不是可以达到以下几个目标呢?
1、抽象。数据访问层利用一个函数就可以应对多个表的添加数据的功能。
2、代码重用。好多地方都可以调用。
3、零耦合。业务层和数据层的真正零偶合。我觉得修改上一层的代码的时候不用修改下一层的代码,这就是零耦合吧;同样修改下一层的代码的时候不用修改上一层的代码,也就是零耦合吧。而这里就是这样。
只要你把数据放在数据库里(有表有字段的那种),而且这种数据库支持“insert into ”这样的标准SQL语句,那么就不需要修改数据访问层!上一层也不用修改。
我觉得这个不能叫做面向对象吧,顶多是利用了“封装”的特性。应该是面向过程的思路。但是应该说使用了 抽象。
优点:
1、再多的表也不用一遍一遍的写组合SQL语句的代码了。(前提是使用SQL语句)。
2、SQL语句完全放在数据访问层里,上一层只出现表名和字段名。
3、代码量少!数据访问层只需要一个函数(还是公用的),也不用实体类来传递数据了,也就少了编写实体类和赋值取值的代码。
4、便于修改,增加字段的话,只需要修改一下数组的大小,加两行代码就可以了。(当然UI里还要加一个控件)。其他的地方,数据访问层了根本就不用修改,根本就没有实体类,所以也就不用修改了。
5、添加、修改一个页面完成。
缺点:
1、虽然逻辑层里没有出现SQL语句,但是依然出现了表名和字段名。相信大家对这一点很是不满意吧。这个确实是一个缺点,但是并不足以否掉这种添加数据的方案。
2、没有使用实体类传递数据(也没有用Hashtable),而使用了数组。我觉得数组很灵活,也很基本,绝大多数语言都是支持的,这里使用数组就足够用了吧。
3、不OO。不知道这个算不算缺点,难道不OO就不能写成程序了吗?
[/b]不好意思,昨天晚上思路有点混乱。有几个前提忘记说明了,现在补充一下。
1、缩小范围。按照由简到难的思路,这里先讨论最简单的添加数据的情况。就是单表的添加和修改;这里讨论的是webform的情况。
2、第一步抽象是针对数据访问层的抽象。
如果我没有理解错的话,现在大多数人的做法是:有一个表(或者几个有关联的表)在数据层里就要有一个“函数”与之对应,
如果采用的是SQL语句的方式的话,那么函数的内筒就是组合SQL语句的代码,
如果采用的是存储过程的方式的话,那么函数的内筒就是给存储过程的参数赋值。
而我这里只需要一个函数就可以了。这个函数是共用的,是针对所有表的。再准确点说:SQL语句对应两个函数(一个添加数据、一个修改数据),存储过程对应一个函数(是添加还是修改在存储过程内部判断)。存储过程的方式在这里没有说明。
3、在这里的代码我想写的尽量简单,写多了就会影响主体,所以这里只写了主要代码。
4、如果您有时间的话,您可以拿我的这段代码(实现添加修改数据功能)和您自己写的类似的功能的代码对应一下,先看一下代码量,然后再看一下如果要增加字段(比如加一个新闻字数),需要修改的代码的数量。
5、第二步抽象是针对后置代码的,也可以叫做逻辑层吧。第三步抽象是针对UI的。
和Artech的思路有些类似。我是想从基础的代码一步一步写上去,我要是直接写我现使用的方式,估计大家不太容易看懂。
6、我的思路是:用简单的代码实现复杂的功能(客户的要求)!
7、怪怪设计论: 抽象无处不在
为了便于说明,先举个实际的例子吧。比如要实现一个发布信息(比如新闻)的功能,说白了就是添加数据。
我的做法是先设计数据库,然后写.aspx (UI),然后写.aspx.cs(后置代码),然后就完成了。
设计数据库:表名叫做 news ,有一下几个字段
NewsID | int | 4 | 主键自增 |
Title | nvarchar | 50 | 标题 |
Kind | int | 4 | 新闻分类 |
Editor | nvarchar | 20 | 编辑 |
Content | ntext | 16 | 新闻内容 |
<form id="Form1" method="post" runat="server">
<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="400" align="center" border="1">
<TR>
<TD align="right">标题:</TD>
<TD>
<hbs:HBSTextBox id="Txt_Title" runat="server" Columns="50"></hbs:HBSTextBox></TD>
</TR>
<TR>
<TD align="right">类别:</TD>
<TD>
<hbs:HBSDropDownList id="Lst_Kind" runat="server" Width="112px"></hbs:HBSDropDownList></TD>
</TR>
<TR>
<TD align="right">作者:</TD>
<TD>
<hbs:HBSTextBox id="Txt_Editor" runat="server" Columns="50"></hbs:HBSTextBox></TD>
</TR>
<TR>
<TD align="right">内容:</TD>
<TD>
<hbs:HBSTextBox id="Txt_Content" runat="server" TextMode="MultiLine" Rows="5" Columns="50"></hbs:HBSTextBox></TD>
</TR>
</TABLE>
<hr color="#39689f">
<TABLE cellSpacing="1" cellPadding="1" width="100%" align="center" border="0">
<TR>
<TD align="center">
<asp:Button id="Btn_Save" runat="server" Width="70px" Text=" 确 定 "></asp:Button> <INPUT id="Btn_Return" type="button" value=" 返 回 " onclick="myEsc()"></TD>
</TD></TR>
</TABLE>
</form>
可以暂时把 hbs:HBSTextBox 当作一般的 TextBox 看待,HBSTextBox 是我继承了TextBox写的一个自定义服务器控件。
后置代码(可以看作逻辑层吧)
private void Page_Load(object sender, System.EventArgs e)
#region 查询语句的方式添加、修改数据
/// <summary>
/// 添加记录。传入表名,字段数组,值数组,返回新生成记录的ID
/// </summary>
/// <param name="TableName">要添加记录的表的名称</param>
/// <param name="ziduan">字段名数组</param>
/// <param name="msg">字段对应的值的数组</param>
/// <returns></returns>
public string InsertDataStr(string TableName , string[] ziduan , string[] msg )
/// <summary>
/// 修改记录。传入表名,字段数组,值数组
/// </summary>
/// <param name="TableName">要修改记录的表的名称</param>
/// <param name="ziduan">字段名数组</param>
/// <param name="msg">字段对应的值的数组</param>
/// <param name="tiaojian">条件 ,加在where 后面的语句</param>
/// <returns></returns>
public bool UpdateData( string TableName ,string[] ziduan ,string[] msg ,string tiaojian)
#endregion
思路呢就是 组合成 insert into 的SQL语句,insert 需要什么信息呢?表名,字段名和字段对应的值。
我把这三个信息用一个字符串和两个数组传递进来,然后用两个for 循环来组合。最后通过 ADO.net 提交给数据库执行。
这样99%以上的表的添加都可以用这个函数了,是不是可以达到以下几个目标呢?
1、抽象。数据访问层利用一个函数就可以应对多个表的添加数据的功能。
2、代码重用。好多地方都可以调用。
3、零耦合。业务层和数据层的真正零偶合。我觉得修改上一层的代码的时候不用修改下一层的代码,这就是零耦合吧;同样修改下一层的代码的时候不用修改上一层的代码,也就是零耦合吧。而这里就是这样。
只要你把数据放在数据库里(有表有字段的那种),而且这种数据库支持“insert into ”这样的标准SQL语句,那么就不需要修改数据访问层!上一层也不用修改。
我觉得这个不能叫做面向对象吧,顶多是利用了“封装”的特性。应该是面向过程的思路。但是应该说使用了 抽象。
优点:
1、再多的表也不用一遍一遍的写组合SQL语句的代码了。(前提是使用SQL语句)。
2、SQL语句完全放在数据访问层里,上一层只出现表名和字段名。
3、代码量少!数据访问层只需要一个函数(还是公用的),也不用实体类来传递数据了,也就少了编写实体类和赋值取值的代码。
4、便于修改,增加字段的话,只需要修改一下数组的大小,加两行代码就可以了。(当然UI里还要加一个控件)。其他的地方,数据访问层了根本就不用修改,根本就没有实体类,所以也就不用修改了。
5、添加、修改一个页面完成。
缺点:
1、虽然逻辑层里没有出现SQL语句,但是依然出现了表名和字段名。相信大家对这一点很是不满意吧。这个确实是一个缺点,但是并不足以否掉这种添加数据的方案。
2、没有使用实体类传递数据(也没有用Hashtable),而使用了数组。我觉得数组很灵活,也很基本,绝大多数语言都是支持的,这里使用数组就足够用了吧。
3、不OO。不知道这个算不算缺点,难道不OO就不能写成程序了吗?
相关文章推荐
- 其实添加数据也可以这样简单——表单的第一步抽象(针对数据访问层)《怪怪设计论: 抽象无处不在 》有感
- 其实添加数据也可以这样简单——表单的第三步抽象(针对UI及后置代码)
- 其实添加数据也可以这样简单——表单的第三步抽象(针对UI及后置代码)
- jquery table表格添加删除数据(含批量删除,全选全不选和简单的表单验证)
- 设置select下拉框只读,提交表单前,设置可读,这样可以提交数据到后台
- Android客户端上传数据到服务器:可以上传简单的表单,也可以方便的上传带有附件的文件
- jQuery简单表单判断,获取框中的数据动态到添加表格
- 其实URL重写也可以这样简单
- 将IRepository接口进行抽象,使它成为数据基类的一个对象,这样每个子类都可以有自己的最基础的CURD了
- json对象load到表单中,这样后台Ajax过来的数据就可以直接加载
- mysql 大量数据插入(可用于数据添加字段不能添加的情况,因为会copy临时表。这样可以手动分批处理)
- Linux下单网卡配置多IP其实可以这样简单
- 原来可以这样简单的说明10维空间的奥秘
- PHP简单系统数据添加以及数据删除模块源文件下载
- jQuery - 动态添加、删除form表单项(附:新增项数据无法提交问题解决)
- 【Easyui】解决未对form表单数据进行校验直接就可以提交的问题
- 用Ado.net可以对数据进行批量添加或更新
- 给jqGrid数据行添加修改和删除操作链接(可以执行)
- Ado.net批量添加和更新数据简单示例
- 简单的ajax+servlet表单数据验证