感觉能从底层控制SQL语句是比较好的。
一个比较简单的O/P MAPING,有兴趣你可以扩充它哟。
主要的核心代码如下,DAOAdapter根据VO生成SQL语句。支持OO。DAO模式,不用我多介绍了吧。不了解可以去看看JAVA。另外通过AOP对 DAO模板进行拦截,依赖注入与控制反转,程序运行时,从一个数据库连接池获得一个连接,注入模板中。彻底实现数据库的移植问题。有兴趣可以和我讨论。
interface
Uses
Classes, DB, Contnrs, SysUtils, uDataTransferObject;
type
TDAOAdapter = class(TPersistent)
public
function GetFldName(tmpFld: String): String;
function IsKeyFld(tmpFld: String): Boolean;
function getKeySQLString(Const pTO: TDataTransferObject): String;
function getMaxCountString(Const pTO: TDataTransferObject): String;
function getSearchSQLString(Const pTO: TDataTransferObject): String;
function getInsertSQLString(Const pTO: TDataTransferObject): String;
function getUpdateSQLString(Const pTO: TDataTransferObject): String;
function getDeleteSQLString(Const pTO: TDataTransferObject): String;
constructor Create;
destructor Destroy;
override;
end;
implementation
uses uMPropList, TypInfo, dialogs;
constructor TDAOAdapter.Create;
begin
inherited Create;
end;
function TDAOAdapter.GetFldName(tmpFld: String): String;
begin
if Uppercase(copy(tmpFld, 1, 3)) = 'PK_' then
Result := Copy(tmpFld, 4, length(tmpFld))
else
if Uppercase(tmpFld) = 'TBNAME' then
Result := ''
else
Result := tmpFld;
end;
function TDAOAdapter.IsKeyFld(tmpFld: String): Boolean;
begin
if Uppercase(copy(tmpFld, 1, 3)) = 'PK_' then
Result := True
else
Result := False;
end;
function TDAOAdapter.getKeySQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpFid, tmpTbname: String;
tmpPropList: TMPropList;
filter: string;
begin
tmpSQL := 'select count(*) as mySum from ';
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := tmpSQL + tmpTbname+ ' where 1=1 and ';
for i:=0 to tmpPropList.PropCount-1do
begin
if (GetFldName(tmpPropList.PropNames)<>'') and (IsKeyFld(tmpPropList.PropNames) = true) then
filter := filter + GetFldName(tmpPropList.PropNames)+'='
else
Continue;
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+' and ';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+' and ';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+' and ';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+' and ';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
filter := filter + QuotedStr('1')+' and ';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
filter := filter + QuotedStr('0')+' and ';
if GetEnumProp(pTO, tmpPropList.Props) = '' then
filter := filter + QuotedStr('0')+' and ';
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+' and ';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+' and ';
end;
end;
Result := Copy(tmpSQL+filter,0, length(tmpSQL+filter)-4);
end;
function TDAOAdapter.getMaxCountString(Const pTO: TDataTransferObject): String;
begin
Result := 'select count(*) as mySum from '+pTO.tbName+ ' where 1=1 ';
end;
function TDAOAdapter.getSearchSQLString(Const pTO: TDataTransferObject): String;
var
i,j: Integer;
tmpSQL, tmpFid, tmpTbname: String;
tmpPropList, tmpProp2: TMPropList;
tmpObj: TObject;
tmpInfo: TTypeInfo;
begin
tmpSQL := 'select ';
if not pTO.isDetail then
begin
//单表情况:
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
for i:=0 to tmpPropList.PropCount-1do
begin
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL + GetFldName(tmpPropList.PropNames) +','
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);
tmpSQL := tmpSQL +' FROM '+tmpTbname+' where 1=1';
Result := tmpSQL;
end
else
begin
//明细表情况:
tmpPropList := pTO.FPropList;
tmpSQL := 'select ';
for i:=0 to tmpPropList.PropCount-1do
begin
case tmpPropList.Props^.PropType^.Kind of
tkClass:
begin
tmpObj := GetObjectProp(pTO, tmpPropList.Props);
tmpProp2 := TDataTransferObject(tmpObj).FPropList;
tmpTbname := TDataTransferObject(tmpObj).tbName;
for j:=0 to tmpProp2.PropCount-1do
begin
if GetFldName(tmpProp2.PropNames[j])<>'' then
tmpSQL := tmpSQL + tmpTbname +'.'+GetFldName(tmpProp2.PropNames[j]) +','
end;
end;
end;
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);
tmpSQL := tmpSQL + ' FROM ';
for i:=0 to tmpPropList.PropCount-1do
begin
case tmpPropList.Props^.PropType^.Kind of
tkClass:
begin
tmpObj := GetObjectProp(pTO, tmpPropList.Props);
tmpProp2 := TDataTransferObject(tmpObj).FPropList;
tmpTbname := TDataTransferObject(tmpObj).tbName;
tmpSQL := tmpSQL + tmpTbname+',';
end;
end;
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);
tmpSQL := tmpSQL + ' Where '+pTO.IndexInfo;
Result := tmpSQL;
end;
end;
function TDAOAdapter.getInsertSQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpTbname: String;
tmpPropList: TMPropList;
begin
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := 'insert '+tmpTbname+' (';
for i:=0 to tmpPropList.PropCount-1do
begin
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL + GetFldName(tmpPropList.PropNames)+','
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1)+') values(';
for i:=0 to tmpPropList.PropCount-1do
begin
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+',';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+',';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+',';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+',';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
tmpSQL := tmpSQL + QuotedStr('1')+',';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
tmpSQL := tmpSQL + QuotedStr('0')+',';
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
tmpSQL := tmpSQL + QuotedStr('0')+',';
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+',';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+',';
end;
end;
Result := Copy(tmpSQL,0, length(tmpSQL)-1)+')';
end;
function TDAOAdapter.getUpdateSQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpTbname: String;
tmpPropList: TMPropList;
filter: String;
begin
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := 'Update '+tmpTbname+' set ';
for i:=0 to tmpPropList.PropCount-1do
begin
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL + GetFldName(tmpPropList.PropNames)+'=';
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+',';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+',';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+',';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+',';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
tmpSQL := tmpSQL + QuotedStr('1')+',';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
tmpSQL := tmpSQL + QuotedStr('0')+',';
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
tmpSQL := tmpSQL + QuotedStr('0')+',';
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+',';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+',';
end;
end;
tmpSQL := Copy(tmpSQL,0, length(tmpSQL)-1);
//主键产生Update语句
filter := ' Where 1=1 and ';
for i:=0 to tmpPropList.PropCount-1do
begin
if (GetFldName(tmpPropList.PropNames)<>'') and (IsKeyFld(tmpPropList.PropNames) = true) then
filter := filter + GetFldName(tmpPropList.PropNames)+'='
else
Continue;
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetOrdProp(pTO, tmpPropList.Props) )+' and ';
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +IntToStr( GetInt64Prop(pTO, tmpPropList.Props) )+' and ';
tkChar, tkLString, tkString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetStrProp(pTO, tmpPropList.Props) )+' and ';
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetSetProp(pTO, tmpPropList.Props) )+' and ';
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
filter := filter + QuotedStr('1')+' and ';
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
filter := filter + QuotedStr('0')+' and ';
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
filter := filter + QuotedStr('0')+' and ';
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +FloatToStr( GetFloatProp(pTO, tmpPropList.Props) )+' and ';
tkWChar, tkWString:
if GetFldName(tmpPropList.PropNames)<>'' then
filter := filter +QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) )+' and ';
end;
end;
Result := Copy(tmpSQL+filter,0, length(tmpSQL+filter)-4);
end;
function TDAOAdapter.getDeleteSQLString(Const pTO: TDataTransferObject): String;
var
i: Integer;
tmpSQL, tmpTbname: String;
tmpPropList: TMPropList;
begin
tmpPropList := pTO.FPropList;
tmpTbname := pTO.tbName;
tmpSQL := 'Delete '+tmpTbname+' where 1=1 ';
for i:=0 to tmpPropList.PropCount-1do
begin
if not( (GetFldName(tmpPropList.PropNames)<>'') and (IsKeyFld(tmpPropList.PropNames) = true)) then
Continue;
case tmpPropList.Props^.PropType^.Kind of
tkInteger:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+IntToStr( GetOrdProp(pTO, tmpPropList.Props) );
tkInt64:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+IntToStr( GetInt64Prop(pTO, tmpPropList.Props) );
tkChar, tkLString, tkString:
if not (Trim( GetStrProp(pTO, tmpPropList.Props) ) = '') and (GetFldName(tmpPropList.PropNames)<>'') then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr( GetStrProp(pTO, tmpPropList.Props) );
tkSet:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr( GetSetProp(pTO, tmpPropList.Props) );
tkEnumeration:
if GetFldName(tmpPropList.PropNames)<>'' then
begin
if GetEnumProp(pTO, tmpPropList.Props) = 'True' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr('1');
if GetEnumProp(pTO, tmpPropList.Props) = 'False' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr('0');
if (GetEnumProp(pTO, tmpPropList.Props) = '') then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr('0');
end;
tkFloat:
if GetFldName(tmpPropList.PropNames)<>'' then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+FloatToStr( GetFloatProp(pTO, tmpPropList.Props) );
tkWChar, tkWString:
if not (Trim( GetStrProp(pTO, tmpPropList.Props) ) = '') and (GetFldName(tmpPropList.PropNames)<>'') then
tmpSQL := tmpSQL +' and '+ GetFldName(tmpPropList.PropNames)+'='+QuotedStr( GetWideStrProp(pTO, tmpPropList.Props) );
end;
end;
Result := tmpSQL;
end;
destructor TDAOAdapter.Destroy;
begin
inherited Destroy;
end;
end.