ASP数据库封装驱动
原来的方案:
我们是首先根据数据库的字段和实际需求设计Web表单,然后从Web表单获取提交的数据集,然后在服务段将提交的数据集和数据库的字段一一对应,然后再一一作过滤和处理……
现在的方案:
直接从数据库生成框架缓存,将每一个表的字段及其相关属性(类型要求、必填、长度、默认值……)储存在全局数组中。当外部提交某张表单时,从对应的全局数组中生成相应的Dictionary对象,然后依据这个和数据表完全映射的Dictionary遍历获取对应的提交值,由此替代了一一对应和读取的繁琐过程。
实现部分被简化为:
for i=0 to Ubound(KeysArray)-1
Key=KeysArray(i,0)
Item=Request(md5(Key))
objDict.Add Key,Item
next
也就是说,这是和传统方案完全相反的思路,这个思路保证了所获取的数据一定是数据库所需要的数据,数据库要求的数据类型或者必须为空的数据如果出现异常则必然会出错,等等。
最后在实现表单处理的语句简化为,其他的一切操作都被封装在类中:
Call System_Initialize()
Dim objUser ''新建对象
Set objUser = new TUser
objUser.Table="Comm_User" ''指定数据表
If objUser.Creat Then ''建立表的Dictionary对象
objUser.ValidAndTransfer() ''获取数据、验证并转入最终的数据驱动层
objUser.Update() ''更新该表数据
End IF
Set objUser = nothing
Call System_Terminate()
与之配套的另外一个方面是从缓存的数据表框架中按照实际表单的需要自动生成Web表单,显示在客户端。
在SQL Server中遍历当前数据库的所有用户表
SELECT Table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE (TABLE_TYPE <> ''VIEW'')
Table_name:表名;
TABLE_TYPE:表的类型;
参见:SQL Server联机手册,T-SQL参考,信息架构视图。
又及:ACCESS下也可实现相关的功能[1]
在SQL Server中遍历指定表的字段及属性
SELECT Column_name,IS_NULLABLE,DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE (TABLE_NAME = ''myTableName'')
TABLE_NAME:表名;
Column_name:列名;
IS_NULLABLE:是否允许为空;
DataType:系统数据类型;
ORDINAL_POSITION:列标识号;
COLUMN_DEFAULT:列的默认值;
CHARACTER_OCTET_LENGTH:以字节为单位的最大长度,适于二进制数据、字符数据,或者文本和图像数据。否则,返回 NULL。
从数据库生成当前库所有表全局Array缓存
strSQL="SELECT Table_name FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_TYPE<>''VIEW'')"
Set objRS_table= objConn.Execute(strSQL)
do while not objRS_table.EOF
strSQL="SELECT Column_name,DATA_TYPE,IS_NULLABLE,COLUMN_DEFAULT,CHARACTER_OCTET_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE (TABLE_NAME = ''"& objRS_table("Table_name") &"'')"
set objRS_column=server.createobject("adodb.recordset")
objRS_column.open strSQL,objConn,1,1
Dim i,TableTemp
i=0
ReDim TableTemp(objRS_column.RecordCount,4)
do while not objRS_column.EOF
TableTemp(i,0)=objRS_column(0)
TableTemp(i,1)=objRS_column(1)
TableTemp(i,2)=objRS_column(2)
TableTemp(i,3)=objRS_column(3)
TableTemp(i,4)=objRS_column(4)
i=i+1
objRS_column.movenext
loop
Set objRS_column= nothing
application(objRS_table(0))=TableTemp
objRS_table.movenext
loop
数据驱动层
<%
''******************************************************
''底层A:对DataBase操作的封装。
''返回错误代码头:DB
''******************************************************
Class TDBDriver
Public objDict
Private Table
Private KeysArray
Private ItemArray
Private objRS
Private strSQL
Private SQL_Start
Private SQL_Main
Private SQL_Join
Private SQL_Where
Private SQL_Order
Private SQL_Group
Public PageSize
Private ErrorMsg
''插入一条数据或者更新指定的条目
Public Function Update()
If objDict.Item(KeysArray(0,0))="" Then
SQL_Start="Insert into "& Table
SQL_Main=" ("
''从有数据的部分对应更新入数据库
For i=1 to objDict.Count-1
If Not ItemArray(i)="" Then
SQL_Main= SQL_Main & KeysArray(i,0) &","
End If
Next
''去掉最后一个“,”
SQL_Main=Left(SQL_Main,Len(SQL_Main)-1)
SQL_Main= SQL_Main &") Values("
For i=1 to objDict.Count-1
If Not ItemArray(i)="" Then
If KeysArray(i,1)="int" Then
SQL_Main= SQL_Main & objDict.Item(KeysArray(i,0))
Else
SQL_Main= SQL_Main &"''"& objDict.Item(KeysArray(i,0)) &"''"
End if
SQL_Main= SQL_Main &","
End If
Next
''去掉最后一个“,”
SQL_Main=Left(SQL_Main,Len(SQL_Main)-1)
SQL_Main= SQL_Main &")"
Else
SQL_Start="Update "& Table &" Set "
For i=1 To objDict.Count-1
If Not ItemArray(i)="" Then
SQL_Main= SQL_Main &" ("& KeysArray(i,0) &"="
If KeysArray(i,1)="int" Then
SQL_Main= SQL_Main & objDict.Item(KeysArray(i,0))
Else
SQL_Main= SQL_Main &"''"& objDict.Item(KeysArray(i,0)) &"''"
End if
SQL_Main= SQL_Main &"),"
End IF
Next
''去掉最后一个“,”
SQL_Main=Left(SQL_Main,Len(SQL_Main)-1)
SQL_Where=" Where "& KeysArray(0,0) &"="& objDict.Item(KeysArray(0,0))
End if
strSQL=SQL_Start & SQL_Main & SQL_Where
''objConn.Execute(strSQL)
Response.Write strSQL
Update=True
End Function
''删除数据
Public Function Delete()
If objDict.Item(KeysArray(0,0))="" Then Call ShowError(ErrorMsg,01) :Exit Function
SQL_Start="Delete From "& Table
SQL_Where=" Where "& KeysArray(0,0) &"="& objDict.Item(KeysArray(0,0))
strSQL=SQL_Start & SQL_Where
objConn.Execute(strSQL)
Delete=True
End Function
''返回单条数据
Public Function ReturnSingle()
If objDict.Item(KeysArray(0,0))="" Then Call ShowError(ErrorMsg,02) :Exit Function
SQL_Start="Select * From "& Table
SQL_Where=" Where "& KeysArray(0,0) &"="& objDict.Item(KeysArray(0,0))
strSQL=SQL_Start & SQL_Where
Set objRS =objConn.Execute(strSQL)
If objRS.EOF or objRS.BOF Then
Call ShowError(ErrorMsg,03)
Else
For i=1 To Ubound(objDict.Items)-1
objDict.Item(KeysArray(i,0)) = objRS(i)
Next
End IF
Set objRS =Nothing
ReturnSingle=objDict
End Function
''返回分页数据
''需要继承回传的数据
Public Function ReturnList()
''必须指定页长、页数
If PageSize="" Then Call ShowError(ErrorMsg,0) :Exit Function
End Function
Public Function Transfer(ExternalDict)
Set objDict=ExternalDict.objDict
''参数导入,只是为了书写方便
Table=ExternalDict.Table
KeysArray=ExternalDict.KeysArray
ItemArray=objDict.Items
End Function
Private Sub Class_Initialize()
ErrorMsg="DB"
''传入FormDriver处理过的Dictionary
End Sub
Private Sub Class_Terminate()
''返回FormDriver处理过的Dictionary
End Sub
End Class
''******************************************************
''******************************************************
''底层B:对Dictionary操作的封装。
''返回错误代码头:DC
''******************************************************
Class TDictionaryDriver
Public Table
Public KeysArray
Public objDict
Private Key
Private Item
Private ErrorMsg
''根据系统缓存导入框架
''报错信息
Public Function Creat()
''必须指定数据表
If Table="" Then Call ShowError(ErrorMsg,01) :Exit Function
''必须是系统缓存中已经存在的数据表
If IsNull(application(Table)) Then Call ShowError(ErrorMsg,02) :Exit Function
''导入数据表框架
KeysArray=application(Table)
End Function
''根据数据表框架-获取[过滤]数据
''通过加密的方案解决表单字段和数据库字段的异步问题
Public Function GetRequest()
for i=0 to Ubound(KeysArray)-1
Key=KeysArray(i,0)
Item=Request(md5(Key))
''Item=Request.QueryString(md5(Key))
''Item=Request.Form(Key)
objDict.Add Key,Item
next
''形成Dictionary对象
GetRequest=True
End Function
''根据数据表框架-效验获取的数据
Public Function Valid()
''注入转换和过滤
''必填项
If objDict.Item(KeysArray(0,0))="" Then
''对于新增数据,必填项目不能为空
''允许更新操作跳过必填项目遍历进行部分更新
for i=1 to Ubound(KeysArray)-1 ''跳过主键遍历
If Trim(KeysArray(i,2))="No" And objDict.Item(KeysArray(i,0))="" Then Call ShowError(ErrorMsg,03) :Exit Function
next
End IF
''字段类型要求
for i=0 to Ubound(KeysArray)-1
''效验数据类型要求
If KeysArray(i,1)="int" Then
If IsNumeric(objDict.Item(KeysArray(i,0)))=0 Then Call ShowError(ErrorMsg,04) :Exit Function
If objDict.Item(KeysArray(i,0))>2147483647 or objDict.Item(KeysArray(i,0))<-2147483647 Then Call ShowError(ErrorMsg,05) :Exit Function
ElseIf objDict.Item(KeysArray(i,0))<>"" And KeysArray(i,1) ="datetime" Then
If IsDate(objDict.Item(KeysArray(i,0)))=0 Then Call ShowError(ErrorMsg,06) :Exit Function
ElseIF KeysArray(i,1)="bit" Then
If (Not objDict.Item(KeysArray(i,0))=0) And (Not objDict.Item(KeysArray(i,0))=1) Then Call ShowError(ErrorMsg,07) :Exit Function
End If
''效验字段长度
If IsNumeric(KeysArray(i,4)) And Len(objDict.Item(KeysArray(i,0)))>=KeysArray(i,4) Then Call ShowError(ErrorMsg,08) :Exit Function
''默认值
next
Valid=True
End Function
''从数据库框架和Dictionary还原出完整的表单,该表单需要具体对象类根据实际需求进行进一步处理
''通过加密的方案解决表单字段和数据库字段的异步问题
Public Function ReturnForm()
Dim strForm
strForm="<form action="""" method=""post"" id="""& MD5(Table) &"""><ul>" &chr(10)
strForm=strForm &"<li><input id="""& MD5(KeysArray(0,0)) &""" type=""hiddden"" value="""& objDict.Item(KeysArray(0,0)) &"""></li>" &chr(10)
for i=0 to Ubound(KeysArray)-1
''效验数据类型
If KeysArray(i,1)="int" Then
''Radio
''Select
''Checkbox
strForm=strForm &"<li><input id="""& MD5(KeysArray(i,0)) &""" type=""text"" value="""& objDict.Item(KeysArray(i,0)) &"""></li>"&chr(10)
ElseIf KeysArray(i,1) ="datetime" Then
strForm=strForm &"<li><input id="""& MD5(KeysArray(i,0)) &""" type=""text"" value="""& objDict.Item(KeysArray(i,0)) &"""></li>"&chr(10)
ElseIF KeysArray(i,1)="bit" Then
strForm=strForm &"<li><input id="""& MD5(KeysArray(i,0)) &""" type=""text"" value="""& objDict.Item(KeysArray(i,0)) &"""></li>"&chr(10)
ElseIF KeysArray(i,1)="text" Then
strForm=strForm &"<li><textarea id="""& MD5(KeysArray(i,0)) &""" type=""text"">"& objDict.Item(KeysArray(i,0)) &"</textarea></li>"&chr(10)
End If
next
strForm=strForm &"</ul><form>" &chr(10)
Response.Write strForm
ReturnForm=True
End Function
Private Sub Class_Initialize()
''创建Dictionary对象
Set objDict=CreateObject("Scripting.Dictionary")
ErrorMsg="DC"
End Sub
Private Sub Class_Terminate()
''释放Dictionary对象
Set objDict=nothing
End Sub
End Class
''******************************************************
''交互层,根据实际需要定制结合对Dictionary和DataBase的操作,定义针对对象的直接操作。
''返回错误代码头:UR
''******************************************************
Class TUser
Public Table
Private objDictionary
Private objDataBase
Private ErrorMsg
Public Function Update()
iF objDataBase.Update Then Update=True
End Function
Public Function Delete()
iF objDataBase.Delete Then Delete=True
End Function
Public Function DrawForm()
iF objDictionary.ReturnForm Then DrawForm=True
End Function
Public Function ValidAndTransfer()
objDictionary.GetRequest()
If objDictionary.Valid Then
Call objDataBase.Transfer(objDictionary)
Else
Call ShowError(ErrorMsg,01) :Exit Function
End If
End Function
Public Function Creat()
If Not Table="" Then
objDictionary.Table=Table
objDictionary.Creat()
End If
Creat=True
End Function
Private Sub Class_Initialize()
ErrorMsg="UR"
Set objDictionary= new TDictionaryDriver
Set objDataBase = new TDBDriver
End Sub
Private Sub Class_Terminate()
Set objDictionary= Nothing
Set objDataBase = nothing
End Sub
End Class
''''''''''''''''''''''''''''''''''''''''''''''''
Call System_Initialize()
Dim objUser
Set objUser = new TUser
objUser.Table="Comm_User"
If objUser.Creat Then
''objUser.ValidAndTransfer()
''objUser.Update()
Call objUser.DrawForm()
End IF
Set objUser = nothing
Call System_Terminate()
''''''''''''''''''''''''''''''''''''''''''''''''
%> from:asp学习网/title:ASP数据库封装驱动/ time:2006-4-26 22:14:25
本文主题ASP数据库封装驱动