在日常开发中,经常会需要进行数据库操作,如执行一些 SQL 查询、或者执行一些 SQL 命令等,如果每次执行操作都按照 Delphi 数据库操作的步骤一步一步地组织语句去执行的话,又显得比较繁琐,所以,有必要对数据库的操作进行封装,以便于在进行数据库操作时,通过简单地调用即可实现。
在本节中,我们通过 Zeos 的数据库组件来实现一个简单的数据库操作封装。代码如下:
unit sqlunit; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, ZConnection, ZDataset, DB, Dialogs; type TSqlStatment = class private sSql: String; public Query: TZQuery; // 构造函数 Constructor Create(Conn: TZConnection); procedure SetSQL(sql: String); procedure Execute; procedure Open; // 析构函数 Destructor Free; end; implementation Constructor TSqlStatment.Create(Conn: TZConnection); begin Query:=TZQuery.Create(nil); Query.Connection:=Conn; end; procedure TSqlStatment.SetSQL(sql: String); begin // 设置 SQL 语句,可以包含参数 sSql:=sql; try Query.Close; Query.SQL.Clear; Query.SQL.Text := sSql; Query.Prepare; except on E: EDatabaseError do MessageDlg('提示', 'DB ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); on E: Exception do MessageDlg('提示', 'ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); end; end; procedure TSqlStatment.Execute; begin // 执行 SQL 语句,适合除 SELECT 语句之外的所有语句 try Query.ExecSQL; except on E: EDatabaseError do MessageDlg('提示', 'DB ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); on E: Exception do MessageDlg('提示', 'ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); end; end; procedure TSqlStatment.Open; begin // 执行 SQL 查询,即 Select 语句 try Query.Open; except on E: EDatabaseError do MessageDlg('提示', 'DB ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); on E: Exception do MessageDlg('提示', 'ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); end; end; Destructor TSqlStatment.Free; begin Query.Destroy; end; end.
通过一段更改用户密码的操作,来看一下通过 TSqlStatment 实例执行 SQL 语句的调用,代码如下:
procedure TPasswordForm.OkButtonClick(Sender: TObject); var SqlStatment: TSqlStatment; Salt, SavedPassword, HashPassword: String; begin // 检查密码的输入情况 if Length(OldEdit.Text) <= 0 then begin MessageDlg('提示', '请输入旧密码!', mtInformation, [mbOk], ''); Exit; end; if Length(NewEdit.Text) <= 0 then begin MessageDlg('提示', '请输入新密码!', mtInformation, [mbOk], ''); Exit; end; if Length(OkEdit.Text) <= 0 then begin MessageDlg('提示', '请输入确认密码!', mtInformation, [mbOk], ''); Exit; end; // 检查旧密码是否正确 SqlStatment:=TSqlStatment.Create(DBDataModule.DBConnection); SqlStatment.SetSQL('select pwd, salt from c_usrs where usr_id = :USR_ID'); SqlStatment.Query.Params.ParamByName('USR_ID').AsString:=CurrentUser.usr_id; SqlStatment.Open; if SqlStatment.Query.RecordCount <= 0 then begin MessageDlg('提示', '找不到用户,无法修改密码!', mtInformation, [mbOk], ''); SqlStatment.Free; Exit; end; SqlStatment.Query.First; Salt:=SqlStatment.Query.FieldByName('salt').AsString; SavedPassword:=SqlStatment.Query.FieldByName('pwd').AsString; HashPassword := MD5Print(MD5String(Salt+OldEdit.Text)); if HashPassword <> SavedPassword then begin MessageDlg('提示', '旧密码不正确, 请重新设置!', mtInformation, [mbOk], ''); SqlStatment.Free; Exit; end; // 检查新密码与确认密码是否相同,如不相同则提示 if NewEdit.Text <> OkEdit.Text then begin MessageDlg('提示', '新密码与确认密码不符, 请重新设置!', mtInformation, [mbOk], ''); Exit; end; // 检查新密码与旧密码是否相同,如相同则没有必要去修改 if OldEdit.Text = NewEdit.Text then begin MessageDlg('提示', '新密码与旧密码相同, 没有必要修改!', mtInformation, [mbOk], ''); Exit; end; // 产生新的 SALT Salt:=GenGUID; // 计算新密码的 MD5 值 HashPassword := MD5Print(MD5String(Salt+NewEdit.Text)); // 更改密码 SqlStatment.SetSQL('update c_usrs set pwd=:PWD, salt=:SALT where usr_id = :USR_ID'); SqlStatment.Query.Params.ParamByName('PWD').AsString:=HashPassword; SqlStatment.Query.Params.ParamByName('SALT').AsString:=Salt; SqlStatment.Query.Params.ParamByName('USR_ID').AsString:=CurrentUser.usr_id; SqlStatment.Execute; SqlStatment.Free; MessageDlg('提示', '密码已更新!', mtInformation, [mbOk], ''); ModalResult:=mrOk; end;