首页 > 开发 > 综合 > 正文

轻松搞定数据访问层[续1]

2024-07-21 02:23:20
字体:
来源:转载
供稿:网友
' clssqlbuilder

‘ by yuhonglai

‘ www.hahait.com

‘ [email protected]



' note:提供重载方法以指明表名称,默认情况下,是传入参数 o 的类型+"tbl_",此时类名称必须是 clsxxx 的形式.

' 如:

' dim rooms as new clsrooms

' sqlbuilder.add(rooms)

' 此时程序将把 clsrooms 转换成 tbl_rooms,以操作数据库表 tbl_rooms

' 如果类名称和数据库表名称不具有上述对应关系,请使用 add(o,"tablename")形式的方法,以显示指定要操作的数据库表的名称



public class sqlbuilder



' 当要生成的sql语句的 where 条件语句很复杂时,用该常量作为 select 方法中 findcondition(hashtable)

' key,例如:要生成 where birth<'2000-4-4' and birth>'1980-1-1' 的复杂条件时,用以下方法:

' dim h as new hashtable

' h.add(complexsql,"_birth<'2000-4-4' and _birth>'1980-1-1'")

' 注意,birth是实体类的属性名称,前面必须有一个下划线 "_"

' 处理时,程序将用实际数据库字段名称代替相应的 _birth



public const complexsql as string = "@complexsql"



' 根具实体类生成相应的 insert ...sql 语句

' 如果与数据库表名称对应的属性时 关键字段而且是自动增加值时(在db.xml文件中seed的值为 1 )

' 那么该属相将忽略,不会出现在返回的 insert... sql语句中

public overloads shared function add(byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return add(o, typestring)

end function



public overloads shared function add(byval o as object, byval tablename as string) as string

try

dim outsql as string

dim tmpstring as string



outsql = "insert into [" & tablename & "]("

tmpstring = ""



dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)



dim row as data.datarow



for each row in dsdb.tables(tablename).rows

if row.item("seed") & "" = "0" then

outsql = outsql & row.item("dbname") & ","

tmpstring = tmpstring & gets(row.item("type")) & "@" & row.item("dbname") & gets(row.item("type")) & ","

end if

next

outsql = outsql.substring(0, outsql.length - 1)

tmpstring = tmpstring.substring(0, tmpstring.length - 1)

outsql = outsql & ") values (" & tmpstring & ")"



for each row in dsdb.tables(tablename).rows

if row.item("seed") & "" <> "1" then

' tmpstring = o.gettype.invokemember(row.item("name"), reflection.bindingflags.getfield or reflection.bindingflags.getproperty, nothing, o, new object() {}) & ""

tmpstring = callbyname(o, ctype(row.item("name"), string).trim, calltype.get) & ""

if tmpstring = "true" then

tmpstring = "1"

elseif tmpstring = "false" then

tmpstring = "0"

end if

outsql = outsql.replace("@" & row.item("dbname"), tmpstring)

end if

next



return outsql.trim

catch ex as exception

throw ex

end try

end function



' 如 add 方法,关键字段不会更新

' 而且关键字段会作为 update....where .... 的 where 的条件出现

public overloads shared function update(byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return update(o, typestring)

end function



public overloads shared function update(byval o as object, byval tablename as string) as string

try

dim outstring as string = ""

dim tmpstring as string

outstring = "update [" & tablename & "] set "

tmpstring = ""

dim wherestring as string = ""



dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)



dim row as data.datarow



for each row in dsdb.tables(tablename).rows

if row.item("key") & "" = "1" then

wherestring = wherestring & row.item("dbname") & "=" & gets(row.item("type")) & "@" & row.item("dbname") & gets(row.item("type")) & " and "

else

tmpstring = tmpstring & row.item("dbname") & "=" & gets(row.item("type")) & "@" & row.item("dbname") & gets(row.item("type")) & ","

end if

next

if wherestring.trim = "" then

throw new exception("必须指定一个以上的主键!")

end if

tmpstring = tmpstring.substring(0, tmpstring.length - 1)

wherestring = wherestring.substring(0, wherestring.length - 4)

outstring = outstring & tmpstring & " where " & wherestring



for each row in dsdb.tables(tablename).rows

' tmpstring = o.gettype.invokemember(row.item("name"), reflection.bindingflags.getfield or reflection.bindingflags.getproperty, nothing, o, new object() {}) & ""

tmpstring = callbyname(o, ctype(row.item("name"), string).trim, calltype.get) & ""

if tmpstring = "true" then

tmpstring = "1"

elseif tmpstring = "false" then

tmpstring = "0"

end if

outstring = outstring.replace("@" & row.item("dbname"), tmpstring)

next



return outstring.trim

catch ex as exception

throw ex

end try

end function



' 更具对象的关键属性(与数据库表的关键字段对应)删除指定的记录

' 对象的其他属性将被忽略

public overloads shared function delete(byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return delete(o, typestring)

end function



public overloads shared function delete(byval o as object, byval tablename as string) as string

try

dim outstring as string = ""

dim tmpstring as string

outstring = "delete from [" & tablename & "] where "

dim wherestring as string = ""



dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)



dim row as data.datarow



for each row in dsdb.tables(tablename).rows

if row.item("key") & "" = "1" then

wherestring = wherestring & row.item("dbname") & "=" & gets(row.item("type")) & "@" & row.item("dbname") & gets(row.item("type")) & " and "

end if

next

if wherestring.trim = "" then

throw new exception("必须指定一个以上的主键!")

end if



wherestring = wherestring.substring(0, wherestring.length - 4)

outstring = outstring & tmpstring & wherestring



for each row in dsdb.tables(tablename).rows

if row.item("key") & "" = "1" then

' tmpstring = o.gettype.invokemember(row.item("name"), reflection.bindingflags.getfield or reflection.bindingflags.getproperty, nothing, o, new object() {}) & ""

tmpstring = callbyname(o, ctype(row.item("name"), string).trim, calltype.get) & ""

outstring = outstring.replace("@" & row.item("dbname"), tmpstring)

end if

next



return outstring.trim

catch ex as exception

throw ex

end try

end function



' 更具对象的关键属性(与数据库表的关键字段对应)判断该对象是否存在于数据库中

' 对象的其他属性将被忽略

public overloads shared function exists(byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return exists(o, typestring)

end function



public overloads shared function exists(byval o as object, byval tablename as string) as string

try

dim outstring as string

outstring = "select count(*) from [" & tablename & "] where "



dim tmpstring as string

dim wherestring as string = ""



dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)



dim row as data.datarow



for each row in dsdb.tables(tablename).rows

if row.item("key") & "" = "1" then

wherestring = wherestring & row.item("dbname") & "=" & gets(row.item("type")) & "@" & row.item("dbname") & gets(row.item("type")) & " and "

end if

next

if wherestring.trim = "" then

throw new exception("必须指定一个以上的主键!")

end if



wherestring = wherestring.substring(0, wherestring.length - 4)

outstring = outstring & tmpstring & wherestring



for each row in dsdb.tables(tablename).rows

if row.item("key") & "" = "1" then

' tmpstring = o.gettype.invokemember(row.item("name"), reflection.bindingflags.getfield or reflection.bindingflags.getproperty, nothing, o, new object() {}) & ""

tmpstring = callbyname(o, ctype(row.item("name"), string).trim, calltype.get) & ""

outstring = outstring.replace("@" & row.item("dbname"), tmpstring)

end if

next



return outstring.trim

catch ex as exception

throw ex

end try

end function



' 生成 first sql语句

public overloads shared function first(byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return first(typestring)

end function



public overloads shared function first(byval tablename as string) as string

dim moudlesql as string

moudlesql = "select * from [%tablename%] where [%key%] in(select min([%key%]) from [%tablename%])"



dim key as string

dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)

dim row as data.datarow

for each row in dsdb.tables(tablename).rows

if row.item("key") = "1" then

key = ctype(row.item("dbname"), string).trim

exit for

end if

next



moudlesql = moudlesql.replace("%tablename%", tablename)

moudlesql = moudlesql.replace("%key%", key)

return moudlesql

end function



public overloads shared function last(byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return last(typestring)

end function



public overloads shared function last(byval tablename as string) as string

dim moudlesql as string

moudlesql = "select * from [%tablename%] where [%key%] in(select max([%key%]) from [%tablename%])"



dim key as string

dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)

dim row as data.datarow

for each row in dsdb.tables(tablename).rows

if row.item("key") = "1" then

key = ctype(row.item("dbname"), string).trim

exit for

end if

next



moudlesql = moudlesql.replace("%tablename%", tablename)

moudlesql = moudlesql.replace("%key%", key)

return moudlesql

end function



public overloads shared function previous(byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return previous(o, typestring)

end function



public overloads shared function previous(byval o as object, byval tablename as string) as string

dim moudlesql as string

moudlesql = "select * from [%tablename%] where [%key%] in(select max([%key%]) from [%tablename%] where [%key%]<%keyvalue%)"



dim key as string

dim propertyname as string

dim propertyvalue as string



dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)

dim row as data.datarow

for each row in dsdb.tables(tablename).rows

if row.item("key") = "1" then

key = ctype(row.item("dbname"), string).trim

propertyname = ctype(row.item("name"), string).trim

exit for

end if

next

' propertyvalue = o.gettype.invokemember(propertyname, reflection.bindingflags.getfield or reflection.bindingflags.getproperty, nothing, o, new object() {}) & ""

propertyvalue = callbyname(o, propertyname, calltype.get) & ""



moudlesql = moudlesql.replace("%tablename%", tablename)

moudlesql = moudlesql.replace("%key%", key)

moudlesql = moudlesql.replace("%keyvalue%", propertyvalue)

return moudlesql

end function



public overloads shared function [next](byval o as object) as string

dim typestring as string = o.gettype.tostring

dim i as int16

i = typestring.indexof("cls") + 3

typestring = "tbl_" & typestring.substring(i, typestring.length - i)

return [next](o, typestring)

end function



public overloads shared function [next](byval o as object, byval tablename as string) as string

dim moudlesql as string

moudlesql = "select * from [%tablename%] where [%key%] in(select min([%key%]) from [%tablename%] where [%key%]>%keyvalue%)"



dim key as string

dim propertyname as string

dim propertyvalue as string



dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)

dim row as data.datarow

for each row in dsdb.tables(tablename).rows

if row.item("key") = "1" then

key = ctype(row.item("dbname"), string).trim

propertyname = ctype(row.item("name"), string).trim

exit for

end if

next

' propertyvalue = o.gettype.invokemember(propertyname, reflection.bindingflags.getfield or reflection.bindingflags.getproperty, nothing, o, new object() {}) & ""

propertyvalue = callbyname(o, propertyname, calltype.get) & ""



moudlesql = moudlesql.replace("%tablename%", tablename)

moudlesql = moudlesql.replace("%key%", key)

moudlesql = moudlesql.replace("%keyvalue%", propertyvalue)

return moudlesql

end function



' 见 public const complexsql 的说明

public shared function [select](byval findcondition as hashtable, byval tablename as string) as string

dim outsql as string

if findcondition.contains(complexsql) then ' 处理复杂类型的 where 从句

outsql = "select * from [" & tablename & "] where " & findcondition(complexsql)

dim row as data.datarow

dim dsdb as new dataset

dsdb.readxml(clspersistant.dbconfigpath)

for each row in dsdb.tables(tablename).rows

outsql = outsql.replace("_" & ctype(row.item("name"), string).trim, "[" & ctype(row.item("dbname"), string).trim & "]")

next

else

outsql = "select * from [" & tablename & "] where "

dim wherestring as string = ""



dim eachkey as object

for each eachkey in findcondition.keys

wherestring = wherestring & ctype(eachkey, string) & "=" & gets(gettypebyname(tablename, ctype(eachkey, string))) & findcondition(eachkey) & gets(gettypebyname(tablename, ctype(eachkey, string))) & " and "

next

if wherestring.length = 0 then

wherestring = "0=0"

else

wherestring = wherestring.substring(0, wherestring.length - 5)

end if

outsql = outsql & wherestring

end if



return outsql

end function



' 返回指定的字段(数据库表字段的名称)的数据类型名称(vb数据类型)

private shared function gettypebyname(byval tablename as string, byval n as string) as string

dim outstr as string

dim dsdb as new data.dataset

dsdb.readxml(clspersistant.dbconfigpath)

dim eachrow as datarow

for each eachrow in dsdb.tables(tablename).rows

if ctype(eachrow.item("dbname"), string).trim.tolower = n.trim.tolower then

outstr = ctype(eachrow.item("type"), string).trim.tolower

exit for

end if

next

return outstr

end function



' 根具数据类型名称,返回空或' sql语句中数字和字符型是否被‘括起来

private shared function gets(byval t as string) as string

dim outstring as string

t = t.tolower.trim

if t = "single" or t = "int16" or t = "int32" or t = "int64" or t = "double" or t = "byte" then

outstring = ""

return outstring

elseif t = "date" or t = "string" then

outstring = "'"

return outstring

end if

end function



end class



发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表