在三层开发中我们不能直接把sql语句写在客户端,虽然软件最终是通过sql和数据库打交道的,这个时候我们该怎么办呢,我们可以通过 客户端传递参数,服务端插件解析参数的方式来解决这个问题,这样还可以避免类似sql注入的漏洞,好了,不多说,本文重点是序列还原 TFDParams
在ClientDatset的时候 我们可以序列化Tparams 为OleVariant (在DBClient单元 UnpackParams /PackageParams)
我在Firedac中还未找到序列化TFDParams的方法,所以自己就模仿PackageParams 写了 TFDParams 和流转和的函数。
(如果哪位高手知道系统有自带的函数,高手我一下哈)
/// <summary>
/// 参数序列化流
/// </summary>
/// <param name="aParams"></param>
/// <returns>TStream</returns>
function TForm1.ParamsToStream(aParams: TFDParams): TStream;
var
QMP: TQMsgPack;
I, Idx, Count: Integer;
begin
QMP := TQMsgPack.Create;
Result := TMemoryStream.Create;
try
Count := 0;
for I := 0 to aParams.Count - 1 do
if aParams[I].ParamType in AllParamTypes then
Inc(Count);
if Count > 0 then
begin
Idx := 0;
for I := 0 to aParams.Count - 1 do
if aParams[I].ParamType in AllParamTypes then
begin
QMP.ForcePath(idx.ToString).ForcePath('Name').AsString := aParams[I].Name;
QMP.ForcePath(idx.ToString).ForcePath('Value').AsVariant := aParams[I].Value;
QMP.ForcePath(idx.ToString).ForcePath('DataType').AsInteger := Ord(aParams[I].DataType);
QMP.ForcePath(idx.ToString).ForcePath('ParamType').AsInteger := Ord(aParams[I].ParamType);
QMP.ForcePath(idx.ToString).ForcePath('Size').AsInteger := aParams[I].Size;
QMP.ForcePath(idx.ToString).ForcePath('Precision').AsInteger := aParams[I].Precision;
QMP.ForcePath(idx.ToString).ForcePath('NumericScale').AsInteger := aParams[I].NumericScale;
Inc(Idx);
end;
end;
QMP.SaveToStream(Result);
finally
QMP.Free;
end;
end;
/// <summary>
/// 流还原成 TFDParams
/// </summary>
/// <param name="Stream"></param>
/// <returns>TFDParams</returns>
function TForm1.StreamTOParams(Stream: TStream): TFDParams;
var
QMP: TQMsgPack;
LParam: TFDParam;
I: Integer;
begin
QMP := TQMsgPack.Create;
Result := TFDParams.Create;
try
Stream.Position := 0;
QMP.LoadFromStream(Stream);
for I := 0 to QMP.Count - 1 do
begin
LParam := TFDParam(Result.Add);
LParam.Name := QMP.ForcePath(i.ToString).ForcePath('Name').AsString;
LParam.DataType := TFieldType(QMP.ForcePath(i.ToString).ForcePath('DataType').AsInteger);
LParam.ParamType := TParamType(QMP.ForcePath(i.ToString).ForcePath('ParamType').AsInteger);
LParam.Size := QMP.ForcePath(i.ToString).ForcePath('Size').AsInteger;
LParam.Precision := QMP.ForcePath(i.ToString).ForcePath('Precision').AsInteger;
LParam.NumericScale := QMP.ForcePath(i.ToString).ForcePath('NumericScale').AsInteger;
LParam.Value := QMP.ForcePath(i.ToString).ForcePath('Value').AsVariant;
end;
finally
QMP.Free;
end;
end;
调用:
TMS := ParamsToStream(FDQuery1.Params);//序列化参数
FDQuery1.Params.Clear;
TMS.Position := 0;
FDQuery1.Params.Assign(StreamToParams(TMS));//还原参数
全部源码 我已经上传到 :
http://download.csdn.net/detail/u013051638/9717314
Q群 Delphi Home 235236282,欢迎delphi 爱好者加入,一起学习、进步。