Подскажите как правильно организовать работу с БД в классах.Есть БД(Sqlite), для работы использую FireDac.
Например структура БД состоит из 3-х таблиц.Сейчас у меня для каждой таблицы свой(боюсь конфликтов в программе) FDQuery.
Основной Unit разросся, поэтому хочу весь функционал перевести в отдельный класс.С классами только начал знакомиться.
Начал писать так:
unit WorkBase;
interface
uses classes, Sysutils, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Error,
FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool,
FireDAC.Stan.Async, FireDAC.Phys, FireDAC.FMXUI.Wait, FireDAC.Stan.Param,
FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, Data.DB, FireDAC.Comp.DataSet,
FireDAC.Comp.Client, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef,
FireDAC.Stan.ExprFuncs, system.Variants;
type
TDBWork = class
private
Bcon: TFDConnection;
BQ: TFDQuery;
procedure beforeconnection(sender: TObject);
function GetCountExe: integer;
public
procedure SetAccaunts(fname, token: string);
function GetAccauntsList: TStringList;
constructor create;
destructor free; // override;
property Count: integer read GetCountExe;
end;
implementation
{ TDBWork }
procedure TDBWork.beforeconnection(sender: TObject);
begin
Bcon.Params.Values['Database'] := ExtractFilePath(ParamStr(0)) + 'base.db';
end;
constructor TDBWork.create;
begin
Bcon := TFDConnection.create(nil);
Bcon.BeforeConnect := beforeconnection;
Bcon.Connected;
Bcon.LoginPrompt := false;
Bcon.Params.Values['LockingMode'] := 'Normal';
Bcon.Params.Values['DriverID'] := 'SQlite';
BQ := TFDQuery.create(nil);
BQ.Connection := Bcon;
end;
destructor TDBWork.free;
begin
Bcon.free;
BQ.free;
// inherited;
end;
function TDBWork.GetCountExe: integer;
begin
BQ.Close;
BQ.SQL.Text := 'select max(id) from exe';
BQ.OpenOrExecute;
result := BQ.RowsAffected;
end;
function TDBWork.GetAccauntsList: TStringList;
begin
result := TStringList.create;
with BQ do
begin
Close;
Open('select * from accaunt');
First;
while not BQ.Eof do
begin
result.Add(BQ.FieldByName('name').AsString);
next;
end;
end;
end;
// добавление аккаунта
procedure TDBWork.SetAccaunts(fname: string; fFirstname: string);
var
rez: variant;
begin
try
with BQ do
begin
Open('select * from accaunt');
rez := Lookup('name', fname, 'name');
if vartype(rez) = varnull then
begin
Close;
SQL.Text := 'insert into accaunt(name,Firstname) values(:n,:t)';
ParamByName('n').AsString := fname;
ParamByName('t').AsString := fFirstname;
ExecSQL;
end;
end;
except
end;
end;
end.
Дальше мне нужно добавить новую функцию для работы со второй таблицей.Вот только теперь думаю, добавлять в constructor еще один query или можно с одим работать.Например для записи в лог.Вдруг гдето в программе обе функции будут использовать этот один query одновременно, например в основном потоке и дополнительном.Или этого быть не может из-за того что компоненты FDConnection и FDQuery создаются динамически и при использовании класса я каждый раз создаю новый экземпляр?
procedure TForm1.Button35Click(Sender: TObject);
var
wb1:TDBWork;
list:TStringList;
s:string;
begin
wb1:=TDBWork.create;
list:=TStringList.Create;
list:=wb1.GetAccauntsList;
showmessage(list.Text);
wb1.free;
list.Free;
end;
Вопрос
Aleks133
Здравствуйте,
Подскажите как правильно организовать работу с БД в классах.Есть БД(Sqlite), для работы использую FireDac.
Например структура БД состоит из 3-х таблиц.Сейчас у меня для каждой таблицы свой(боюсь конфликтов в программе) FDQuery.
Основной Unit разросся, поэтому хочу весь функционал перевести в отдельный класс.С классами только начал знакомиться.
Начал писать так:
unit WorkBase; interface uses classes, Sysutils, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.FMXUI.Wait, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs, system.Variants; type TDBWork = class private Bcon: TFDConnection; BQ: TFDQuery; procedure beforeconnection(sender: TObject); function GetCountExe: integer; public procedure SetAccaunts(fname, token: string); function GetAccauntsList: TStringList; constructor create; destructor free; // override; property Count: integer read GetCountExe; end; implementation { TDBWork } procedure TDBWork.beforeconnection(sender: TObject); begin Bcon.Params.Values['Database'] := ExtractFilePath(ParamStr(0)) + 'base.db'; end; constructor TDBWork.create; begin Bcon := TFDConnection.create(nil); Bcon.BeforeConnect := beforeconnection; Bcon.Connected; Bcon.LoginPrompt := false; Bcon.Params.Values['LockingMode'] := 'Normal'; Bcon.Params.Values['DriverID'] := 'SQlite'; BQ := TFDQuery.create(nil); BQ.Connection := Bcon; end; destructor TDBWork.free; begin Bcon.free; BQ.free; // inherited; end; function TDBWork.GetCountExe: integer; begin BQ.Close; BQ.SQL.Text := 'select max(id) from exe'; BQ.OpenOrExecute; result := BQ.RowsAffected; end; function TDBWork.GetAccauntsList: TStringList; begin result := TStringList.create; with BQ do begin Close; Open('select * from accaunt'); First; while not BQ.Eof do begin result.Add(BQ.FieldByName('name').AsString); next; end; end; end; // добавление аккаунта procedure TDBWork.SetAccaunts(fname: string; fFirstname: string); var rez: variant; begin try with BQ do begin Open('select * from accaunt'); rez := Lookup('name', fname, 'name'); if vartype(rez) = varnull then begin Close; SQL.Text := 'insert into accaunt(name,Firstname) values(:n,:t)'; ParamByName('n').AsString := fname; ParamByName('t').AsString := fFirstname; ExecSQL; end; end; except end; end; end.
Дальше мне нужно добавить новую функцию для работы со второй таблицей.Вот только теперь думаю, добавлять в constructor еще один query или можно с одим работать.Например для записи в лог.Вдруг гдето в программе обе функции будут использовать этот один query одновременно, например в основном потоке и дополнительном.Или этого быть не может из-за того что компоненты FDConnection и FDQuery создаются динамически и при использовании класса я каждый раз создаю новый экземпляр?
procedure TForm1.Button35Click(Sender: TObject); var wb1:TDBWork; list:TStringList; s:string; begin wb1:=TDBWork.create; list:=TStringList.Create; list:=wb1.GetAccauntsList; showmessage(list.Text); wb1.free; list.Free; end;
ps Сильно не ругайте, только учусь.
Ссылка на комментарий
7 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.