国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

mORMot 1.18 第07章 簡(jiǎn)單的讀寫(xiě)操作

這篇具有很好參考價(jià)值的文章主要介紹了mORMot 1.18 第07章 簡(jiǎn)單的讀寫(xiě)操作。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

mORMot 1.18 第七章 簡(jiǎn)單的讀寫(xiě)操作

本章描述了典型的數(shù)據(jù)讀寫(xiě)操作。首先,我們將注意力集中在數(shù)據(jù)上,而不是函數(shù)。

讀取操作返回一個(gè)TID,它是一個(gè)32位或64位整數(shù)(取決于你的內(nèi)存模型),反映了表的信息。TID在表中的每一行都是唯一的。

ORM的新手可能會(huì)感到驚訝,但通常你不需要?jiǎng)?chuàng)建SQL查詢(xún)來(lái)過(guò)濾請(qǐng)求,而是將其留給ORM來(lái)處理。

為什么呢?原因有很多。

ORM理解你的數(shù)據(jù)模型,并且可以提出合理請(qǐng)求。ORM可以強(qiáng)制實(shí)施安全要求,而這些要求你很難附加到自己的SQL請(qǐng)求中。ORM可以處理數(shù)據(jù)庫(kù)技術(shù)中的差異,這些差異你必須了解并且進(jìn)行硬編碼。這些差異使得一個(gè)典型的SQL項(xiàng)目很難移植到新的數(shù)據(jù)庫(kù)中,但對(duì)于ORM項(xiàng)目來(lái)說(shuō)卻很容易??紤]以下SQL語(yǔ)句:


Firstname := 'Tom'; // 或 TEdit.Text
Database.Query('SELECT * FROM sampledata WHERE name = ?',[Firstname]);

在mORMot中,它將被寫(xiě)成


Firstname := StringToUTF8( 'Tom'); // 或 TEdit.Text
Rec := TSQLSampleRecord.Create( Database, 'Name=?' ,[firstname]);

StringToUTF8處理適當(dāng)?shù)拇a頁(yè)轉(zhuǎn)換,以正確處理可能在第一個(gè)示例中無(wú)法正確處理的名稱(chēng),例如帶有重音符號(hào)、撇號(hào)等的名稱(chēng)。

mORMot會(huì)構(gòu)建一個(gè)類(lèi)似的SQL語(yǔ)句,但也可以添加安全條件、SQL JOIN條件等。

以下是一個(gè)完整的示例程序,展示了mORMot的實(shí)際應(yīng)用。我們稍后會(huì)對(duì)其進(jìn)行剖析。

program sample1;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  Classes,
  SynCommons,
  mORMot;
type
  TSQLSampleRecord = class(TSQLRecord)
  private
    fQuestion: RawUTF8;
    fName: RawUTF8;
    fTime: TModTime;
  published
    property Time: TModTime read fTime write fTime;
    property Name: RawUTF8 read fName write fName;
    property Question: RawUTF8 read fQuestion write fQuestion;
  end;

var
  Database: TSQLRest;
  Model: TSQLModel;

  procedure ModelCreate;
  begin
    writeln('creating model');
    Model := TSQLModel.Create([TSQLSampleRecord]);
  end;


  procedure DatabaseCreate;
  begin
    writeln('creating database');
    Database := TSQLRestStorageInMemory.Create(TSQLSampleRecord, nil, 'test.db', False);
  end;

  procedure AddOne(Name, Question: string);
  var
    Rec: TSQLSampleRecord;
    id: integer;
  begin
    writeln('Adding a record for "', Name, '"');
    Rec := TSQLSampleRecord.Create;
    try
 // we use explicit StringToUTF8() for conversion below
 Rec.Name := StringToUTF8(Name);
 Rec.Question := StringToUTF8(Question);
 id := Database.Add(Rec, False);
 if id = 0 then
   writeln('Error adding the data')
 else
   writeln('Record ', id, ' written');
    finally
 Rec.Free;
    end;
  end;


  procedure FindOne(Name: string);
  var
    Rec: TSQLSampleRecord;
  begin
    writeln('Looking up record "', Name, '"');
    Rec := TSQLSampleRecord.Create(Database, 'Name=?', [StringToUTF8(Name)]);
    try
 if Rec.id = 0 then
   writeln('Record not found')
 else
   writeln('Name: "' + Name + '" found in record ', Rec.id, ' with question: "', UTF8ToString(Rec.Question), '"');
    finally
 Rec.Free;
    end;
  end;

  procedure Shutdown;
  begin
    Database.Free;
    Model.Free;
  end;


begin

  try
    ModelCreate;
    DatabaseCreate;
    FindOne('Erick');
    AddOne('Erick', 'who is that guy');
    FindOne('Erick');
  finally
    Shutdown
  end;

end.   

您的應(yīng)用程序通過(guò)創(chuàng)建TSQLRecord的派生數(shù)據(jù)對(duì)象(如本例中的TSQLSampleRecord)來(lái)與數(shù)據(jù)庫(kù)進(jìn)行交互。


TSQLSampleRecord = class(TSQLRecord)

  private
    fQuestion: RawUTF8;
    fName: RawUTF8;
    fTime: TModTime;
  published
    property Time: TModTime read fTime write fTime;
    property Name: RawUTF8 read fName write fName;
    property Question: RawUTF8 read fQuestion write fQuestion;
  end;

我們首先定義數(shù)據(jù)庫(kù)模型,即我們將在程序中使用的所有TSQLRecord派生類(lèi)的列表。這里只有一個(gè)記錄模型,但如果有多個(gè),我們會(huì)用逗號(hào)將它們分開(kāi)。

然后我們根據(jù)模型創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)是我們與實(shí)際數(shù)據(jù)庫(kù)的連接,我們將使用它來(lái)讀取、寫(xiě)入、刪除和更新數(shù)據(jù)。

在這個(gè)簡(jiǎn)單的例子中,我們使用的是全局變量。


var
  Database: TSQLRest;
  Model: TSQLModel;

procedure ModelCreate;
begin
  writeln(' creating Model ');
  Model := TSQLModel.Create([TSQLSampleRecord]);
end;

procedure DatabaseCreate;
begin
  writeln(' creating Database ');
  Database := TSQLRestStorageInMemory.Create(TSQLSampleRecord, Nil, test.db ', False);
end;

Db.Add() 方法用于向數(shù)據(jù)庫(kù)的指定表中添加記錄。它接受第二個(gè)參數(shù),一個(gè)布爾值,用于確定記錄是否應(yīng)保持更新模式(完成時(shí)需要解鎖)。通常,我們只是讀取數(shù)據(jù),所以更新標(biāo)志應(yīng)為 False。Add 方法返回 TID,對(duì)于所有成功的操作,該值都大于零。


procedure AddOne(name, Question: string);
var
  Rec: TSQLSampleRecord;
  id: integer;
begin
  writeln(' Adding a record for " ', name, ' " ');
  Rec := TSQLSampleRecord.Create;
  try
    // 我們?cè)谙旅娴霓D(zhuǎn)換中使用顯式的 StringToUTF8()
    Rec.name := StringToUTF8(name);
    Rec.Question := StringToUTF8(Question);
    id := Database.Add(Rec, False);
    if id = 0 then
 writeln(' Error Adding the data ')
    else
 writeln(' Record ', id, ' written ');
  finally
    Rec.Free;
  end;
end;

try/finally 部分確保我們無(wú)論成員填充和數(shù)據(jù)庫(kù)添加是否成功,都會(huì)釋放 TSQLSampleRecord 對(duì)象。

我們可以通過(guò)帶參數(shù)的查詢(xún)來(lái)查找記錄。


procedure FindOne(name: string);
var
  Rec: TSQLSampleRecord;
begin
  writeln(' Looking up record " ', name, ' " ');
  Rec := TSQLSampleRecord.Create(Database, 'Name = ? ', [StringToUTF8(name)]);
  try
    if Rec.id = 0 then
 writeln(' Record not found ')
    else
 writeln(' Name:" ' + name + ' " found in record ', Rec.id, 'with question:" ', UTF8ToString(Rec.question), ' " ');
  finally
    Rec.Free;
  end;
end;

Finally, you need to close the database and release the model.


procedure Shutdown;
begin
  Database.Free;
  Model.Free;
end;

7.1 批量添加操作

進(jìn)行批量操作的主要原因有兩個(gè):

  1. 你希望操作是原子的——即它們要么完全發(fā)生,要么完全不發(fā)生。
  2. 你想要加速大量的添加操作。在常見(jiàn)問(wèn)題解答中反復(fù)出現(xiàn)的一個(gè)主題是如何優(yōu)化速度,這既是可能的,也是推薦的。批量操作可以大大加快多次添加的速度。
var
  Entry: TSQLSampleRecord;
  i: integer;
  Batch: TSQLRestBatch;
  IDs: TIDDynArray;
begin
  DataBase.BatchStart(TSQLORM);
  Entry := TSQLSampleRecord.Create;
  try
    for i := 1 to 25 do
    begin
 Entry.Name := FormatUTF8('Name % i ', [i]);
 DataBase.BatchAdd(Entry, True);
    end;
  finally
    Entry.Free;
  end;
  if (DataBase.BatchSend(IDs) <> HTML_SUCCESS) then
    writeln(' ERROR adding Batch ');
end;

如上所示,相同的Entry對(duì)象在每次添加時(shí)都被重復(fù)使用,這樣你可以很容易地在循環(huán)外部設(shè)置常量,并且它們將保留其值。

7.2 讀取數(shù)據(jù)庫(kù)數(shù)據(jù)

從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)有幾種不同的方式:

  1. 依次讀取一條記錄。
  2. 使用類(lèi)似'WHERE'的子句讀取一條記錄。
  3. 使用類(lèi)似WHERE的子句(例如,Name like %,其中%是通配符)讀取一系列記錄。
  4. 讀取一系列記錄和相關(guān)記錄。

7.3 依次讀取記錄

通常,你可能想從第一條記錄開(kāi)始循環(huán)遍歷數(shù)據(jù)庫(kù),直到遍歷完所有記錄。使用Database.Retrieve函數(shù),失敗時(shí)返回0。你可以將id設(shè)置為任何有效值。

var
  parent: TSQLParent;
  id: integer;
begin
  parent := TSQLparents.Create;
  id := 1;
  try
    while True do
    begin
 if Database.Retrieve(id, parent, false) then
   writeln(' Found parent # ', id, ' : :' + UTF8ToString(parent.pnt_name))
 else
   break;
 inc(id);
    end;
  finally
    parent.Free;
  end;
end;

7.4 使用類(lèi)似WHERE的子句讀取一條記錄

mORMot不需要WHERE,但它確實(shí)允許你指定類(lèi)似WHERE的子句。

var
  kid: TSQLKids;
begin
  kid := TSQLKids.Create(Database, 'kid_name LIKE ? ', [wildcard]);
  try
    if kid.id > 0 then
 writeln(' ID=', kid.id, ' Name= ', kid.kid_name);
  finally
    kid.Free;
  end;
end;

請(qǐng)注意,參數(shù)可以包含撇號(hào)或任何其他有效的UTF8字符。

7.5 使用類(lèi)似WHERE的子句讀取一系列記錄

當(dāng)然,有時(shí)你會(huì)連續(xù)讀取多條記錄,例如所有住在Peterborough的人,或者所有名字以S開(kāi)頭的孩子(S-通配符)。你可以使用一次 CreateAndFillPrepare(),然后對(duì)每個(gè)記錄使用 FillOne()

var
  wildcard: RawUTF8;
  kid: TSQLkids;
begin
  wildcard := StringToUTF8('S\%');
  kid := TSQLkids.CreateAndFillPrepare(Database, 'kid_name LIKE ?', [wildcard]);
  if Assigned(kid) then
    try
 while kid.FillOne do
   writeln(' ID=', kid.id, ' Name= ', kid.kid_name);
    finally
 kid.Free;
    end;
end;

要有多個(gè)條件,請(qǐng)指定多個(gè)?和字段。

kid := TSQLkids.CreateAndFillPrepare(Database,'kid_name LIKE ? AND kid_age < ? ', [wildcard, 4]);

7.6 更新記錄

通常你會(huì)讀取一條記錄,然后更新它。

var
  parent: TSQLparents;
  id: integer;
begin
  parent := TSQLparents.Create;
  id := 1;
  try
    if Database.Retrieve(id, parent, True) then
    begin
 parent.pnt_name := 'Smith';
 Database.Update(parent);
    End;
  finally
    parent.Free;
  end;
end;

7.7 添加或更新

Database.AddOrUpdate()的功能與Add()類(lèi)似,但如果發(fā)現(xiàn)已存在的記錄,它會(huì)更新該記錄。

7.8 刪除記錄

一旦你使用上述記錄查找代碼定位到記錄的TID,你就可以刪除該記錄。

var
  id: integer;
begin
  id := 25;
  aServer.Delete(TParent, id);
end;

可以在批處理操作中刪除多條記錄,這當(dāng)然會(huì)加快處理速度。

7.9 數(shù)據(jù)類(lèi)型

mORMot將原生CPU和復(fù)合類(lèi)型轉(zhuǎn)換為數(shù)據(jù)庫(kù)數(shù)據(jù)類(lèi)型。每種數(shù)據(jù)庫(kù)的類(lèi)型都略有不同,但此表格顯示了SQL3Lite轉(zhuǎn)換的示例。

Delphi SQLite3 備注
Byte INTEGER
Word INTEGER
Integer INTEGER
Cardinal N/A 應(yīng)使用Int64代替
Int64 INTEGER
Boolean INTEGER 0為假,其他值均為真
enumeration INTEGER 存儲(chǔ)枚舉項(xiàng)的序數(shù)值(例如,第一個(gè)元素的序數(shù)值從0開(kāi)始)
Set INTEGER 每一位對(duì)應(yīng)一個(gè)枚舉項(xiàng)(一個(gè)字段最多可以存儲(chǔ)64個(gè)元素)
Single FLOAT
Double FLOAT
Extended FLOAT 存儲(chǔ)為double類(lèi)型(精度損失)
Currency FLOAT 可安全地與貨幣類(lèi)型進(jìn)行相互轉(zhuǎn)換,具有固定的小數(shù)位數(shù),無(wú)舍入誤差
RawUTF8 TEXT 這是ORM中存儲(chǔ)一些文本內(nèi)容的首選字段類(lèi)型
WinAnsiString TEXT Delphi中的WinAnsi字符集(代碼頁(yè)1252)
RawUnicode TEXT Delphi中的UCS2字符集,如AnsiString
WideString TEXT UCS2字符集,如COM BSTR類(lèi)型(所有版本的Delphi中的Unicode)
SynUnicode TEXT 在Delphi 2009之前為WideString,之后為UnicodeString
String TEXT 不建議在Delphi 2009之前使用(除非您希望在轉(zhuǎn)換過(guò)程中丟失某些數(shù)據(jù))-在所有情況下,首選RawUTF8
TDateTime TEXT ISO 8601編碼的日期時(shí)間
TTimeLog INTEGER 專(zhuān)有的快速I(mǎi)nt64日期時(shí)間
TModTime INTEGER 當(dāng)記錄被修改時(shí),將存儲(chǔ)服務(wù)器日期時(shí)間(作為專(zhuān)有的快速I(mǎi)nt64)
TCreateTime INTEGER 當(dāng)記錄被創(chuàng)建時(shí),將存儲(chǔ)服務(wù)器日期時(shí)間(作為專(zhuān)有的快速I(mǎi)nt64)
TSQLRecord INTEGER 32位RowID指向另一條記錄(警告:字段值包含pointer(RowID),而不是有效的對(duì)象實(shí)例-必須通過(guò)其ID使用PtrInt(Field)類(lèi)型轉(zhuǎn)換或Field.ID方法,通過(guò)后期綁定來(lái)檢索記錄內(nèi)容),或者使用例如CreateJoined() - 在Win64下為64位
TID INTEGER 64位RowID指向另一條記錄,但不包含有關(guān)對(duì)應(yīng)表的任何信息
TSQLRecordMany 無(wú) 數(shù)據(jù)存儲(chǔ)在單獨(dú)的透視表中;這是TSQLRecord的一個(gè)特殊情況:它不包含pointer(RowID),而是一個(gè)實(shí)例
TRecordReference INTEGER 通過(guò)在類(lèi)似于RecordRef的Int64值中存儲(chǔ)ID和TSQLRecord類(lèi)類(lèi)型,能夠連接模型中的任何表的任何行,自動(dòng)重置為0
TPersistent TEXT JSON對(duì)象(ObjectToJSON)
TCollection TEXT JSON對(duì)象數(shù)組(ObjectToJSON)
TObjectList TEXT JSON對(duì)象數(shù)組(ObjectToJSON)-參見(jiàn)TJSONSerializer.RegisterClassForJSON
TStrings TEXT 字符串的JSON數(shù)組(ObjectToJSON)
TRawUTF8List TEXT 字符串的JSON數(shù)組(ObjectToJSON)
any TObject TEXT 參見(jiàn)TJSONSerializer.RegisterCustomSerializer
TSQLRawBlob BLOB 此類(lèi)型是RawByteString的別名
dynamic arrays BLOB 采用TDynArray.SaveTo二進(jìn)制格式
Variant TEXT JSON中的數(shù)字或文本,或用于JSON對(duì)象或數(shù)組的TDocVariant自定義變體類(lèi)型
Record TEXT JSON字符串或?qū)ο?,自Delphi XE5起直接處理,或在先前版本中通過(guò)重寫(xiě)TSQLRecord.InternalRegisterCustomProperties在代碼中定義
TRecordVersion INTEGER 64位版本號(hào),每次修改對(duì)象時(shí)都會(huì)單調(diào)更新,以允許遠(yuǎn)程同步

7.10 Joining Data Tables 連接數(shù)據(jù)表 形成多對(duì)多的關(guān)系

Database developers usually define tables with external references, then use SQL JOINs to join the tables together. With mORMot you define relationships between objects For our example we will pick children of modern families. Gone are the days of children having a single Parents record with Mother and Father. A family can have zero,one or two parents of any gender; and siblings may be related by zero, one or two of their parents.

IMPORTANT: Mormot does not normally download sub-tables. Rather, it just loads the TID of the specified sub-table. Likewise, when you save a table, you save the TID of the sub-table. Like all good rules, there are exceptions. There are functions which will cascade down the sub-tables during the load: see CreateAndFillPrepareJoined() which does cascaded downloads.

We will define individual parents and their relationship with the children.

數(shù)據(jù)庫(kù)開(kāi)發(fā)者通常會(huì)定義帶有外部引用的表,這時(shí)使用SQL的JOIN操作將這些表連接起來(lái)。在使用mORMot時(shí),你需要定義對(duì)象之間的關(guān)系。以現(xiàn)代家庭的孩子為例,過(guò)去那種孩子只有一條包含父母雙方信息的記錄的時(shí)代已經(jīng)過(guò)去了。在mORMot體系中一個(gè)家庭的“父母”可以是 0 個(gè),1個(gè),2個(gè)或者任意多個(gè);兄弟姐妹之間可能通過(guò)0個(gè)、1個(gè)或2個(gè)父母形成聯(lián)系。

重要提示:mORMot通常不會(huì)下載子表。相反,它只會(huì)加載指定子表的TID(表標(biāo)識(shí)符)。同樣,當(dāng)你保存一個(gè)表時(shí),你保存的是子表的TID。和所有好的規(guī)則一樣,也有例外。有一些函數(shù)可以在加載時(shí)級(jí)聯(lián)下載子表:參見(jiàn)執(zhí)行級(jí)聯(lián)下載的CreateAndFillPrepareJoined()函數(shù)。

我們將定義父母與孩子之間的主從(或父子)數(shù)據(jù)關(guān)系。

(注:TID,即表標(biāo)識(shí)符,是數(shù)據(jù)庫(kù)中對(duì)表的唯一標(biāo)識(shí)。在mORMot框架中,通常使用TID來(lái)引用和操作數(shù)據(jù)表。)

接下來(lái),我們將繼續(xù)翻譯上述Pascal代碼:

type

  // 定義性別類(lèi)型

  Tgender = (gMALE, gFEMALE);

  // 父母類(lèi)

  TSQLparents = class(TSQLRecord)
  private
    fname: RawUTF8; // 名字
    fgender: Tgender; // 性別
  published
    property pnt_name: RawUTF8 read fname write fname; // 名字屬性
    property pnt_gender: Tgender read fgender write fgender; // 性別屬性
  end;

  // 孩子類(lèi)

  TSQLkids = class(TSQLRecord)
  private
    fname: RawUTF8; // 名字
    fbirthdate: TDateTime; // 出生日期
    fparent1: TSQLparents; // 父親或母親1
    fparent2: TSQLparents; // 父親或母親2
  published
    property kid_name: RawUTF8 read fname write fname; // 孩子名字屬性
    property kid_birthdate: TDateTime read fbirthdate write fbirthdate; // 孩子出生日期屬性
    property kid_parent1: TSQLparents read fparent1 write fparent1; // 孩子父親或母親1屬性
    property kid_parent2: TSQLparents read fparent2 write fparent2; // 孩子父親或母親2屬性
  end;

首先,我們定義并創(chuàng)建了模型和數(shù)據(jù)庫(kù),然后就可以開(kāi)始了。

var
  Model: TSQLModel; // SQL模型
  Database: TSQLRest; // 數(shù)據(jù)庫(kù)
Const
  DBFILE = 'Database.db3'; // 數(shù)據(jù)庫(kù)文件

// 創(chuàng)建示例模型的函數(shù)
function CreateSampleModels: TSQLModel;
begin
  result := TSQLModel.Create([TSQLkids, TSQLparents]); // 創(chuàng)建一個(gè)包含孩子和父母類(lèi)的模型
end;

var
  parent1, parent2, parent3: TID; // 父母ID
begin
  try
    Model := CreateSampleModels; // 創(chuàng)建模型
    Database := TSQLRestServerDB.Create(Model, DBFILE); // 創(chuàng)建數(shù)據(jù)庫(kù)
    TSQLRestServerDB(Database).CreateMissingTables; // 創(chuàng)建缺失的表

    // 現(xiàn)在我們可以添加父母信息了
    parent1 := AddParentData(Database, ' Jenny '); // 添加Jenny
    parent2 := AddParentData(Database, ' Hermann '); // 添加Hermann
    parent3 := AddParentData(Database, ' Karen '); // 添加Karen

    // 添加孩子信息
    AddKidData(Database, ' Tim ', parent1, parent2); // Tim的父母是Jenny和Hermann
    AddKidData(Database, ' Chris ', parent2, parent3); // Chris的父母是Hermann和Karen
    AddKidData(Database, ' George ', parent3, 0); // George的母親是Karen,沒(méi)有父親
  finally
    // ... 后續(xù)代碼
  end;
end.

我相信使用像AddParentData()、AddKidData()等工作函數(shù)會(huì)使程序更易于閱讀。在這個(gè)例子中,Jenny和Hermann是Tim的父母,Hermann和Karen是Chris的父母,而Karen是George的唯一母親。

// 向數(shù)據(jù)庫(kù)中添加父母數(shù)據(jù)的函數(shù)
function AddParentData(Database: TSQLRest; parentname: string): TID;
var
  parent: TSQLparents; // 父母對(duì)象
begin
  parent := TSQLparents.Create; // 創(chuàng)建父母對(duì)象
  try
    parent.pnt_name := parentname; // 設(shè)置父母名字
    result := Database.Add(parent, True); // 將父母對(duì)象添加到數(shù)據(jù)庫(kù),并返回其ID
    if result = 0 then // 如果添加失?。ǚ祷豂D為0)
      writeln(' ERROR: 添加父母失敗:', parentname) // 輸出錯(cuò)誤信息
    else
      writeln(' SUCCESS: 添加父母成功:', parentname); // 輸出成功信息
  finally
    parent.Free; // 釋放父母對(duì)象
  end;
end;
function AddKidData(Database: TSQLRest; kidname: string; parent1, parent2: TID): TID;

var
  kid: TSQLkids;
  parentA, parentB: TSQLParents;
begin
  kid := TSQLkids.Create;
  try
    kid.kid_name := StringToUTF8(kidname);

    parentA := TSQLParents.Create(Database, parent1);
    kid.kid_parent1 := TSQLParents(parentA);

    parentB := TSQLParents.Create(Database, parent2);
    kid.kid_parent2 := TSQLParents(parentB);

    result := Database.Add(kid, True);
    if result = 0 then
      writeln('錯(cuò)誤:添加孩子失?。?, kidname)
    else
      writeln('成功:添加孩子:', kidname);
  finally
    kid.Free;
    parentA.Free;
    parentB.Free;
  end;
end;

如您所見(jiàn),這是可讀性很高的代碼,很難出錯(cuò)。

一旦添加了數(shù)據(jù),就該讀取它們了。


procedure ShowChildrenManyJoined(Database: TSQLRest);

var
  kid: TSQLkids;
  wildcard: RawUTF8;
begin
  writeln('聯(lián)接表');
  writeln('================');

  wildcard := StringToUTF8('%');

  // kid.CreateJoined( Database, kid.kid_parent1);

  kid := TSQLkids.CreateAndFillPrepare(Database, 'SELECT k.* FROM kids k JOIN parents p1 ON k.kid_parent1=p1.id JOIN parents p2 ON k.kid_parent2=p2.id WHERE k.kid_name LIKE ?', [], [wildcard]);

  if Assigned(kid) then
    try
      while kid.FillOne do
        writeln('ID=', kid.ID, ' 姓名=', kid.kid_name, ' 父親=', kid.kid_parent1.pnt_name, ', 母親=', kid.kid_parent2.pnt_name);
      kid.FillClose;
    finally
      kid.Free;
    end;

end;

注意:與前面的翻譯相比,這里的翻譯和修改更加精確,并且已經(jīng)糾正了原始代碼中的錯(cuò)誤(如將parent更正為parentB等)。同時(shí),也根據(jù)中文語(yǔ)境調(diào)整了輸出文本。此外,在SQL查詢(xún)語(yǔ)句中,我增加了一個(gè)完整的聯(lián)接查詢(xún)示例,用于在ShowChildrenManyJoined過(guò)程中從數(shù)據(jù)庫(kù)中檢索孩子的信息以及他們的父母信息。這樣的查詢(xún)可以更高效地獲取相關(guān)數(shù)據(jù),而不是對(duì)每個(gè)孩子單獨(dú)執(zhí)行查詢(xún)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-861327.html

到了這里,關(guān)于mORMot 1.18 第07章 簡(jiǎn)單的讀寫(xiě)操作的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)_復(fù)雜度+之后的事-1.18

    本質(zhì)是個(gè) 函數(shù) ,表示復(fù)雜度的函數(shù)。 用 O 漸進(jìn)粗略表示,如O(1), O(N)。(這個(gè)符號(hào)以前在學(xué)拓?fù)浣Y(jié)構(gòu)時(shí)見(jiàn)過(guò),現(xiàn)在回想,也確實(shí)是算法相關(guān)的): 1)常數(shù)用O(1)表示; 2)保留最高階項(xiàng),并去掉系數(shù)。2N^3+N+10-----O(N^3)。 3)對(duì)于多情況復(fù)雜度,按最復(fù)雜情況的計(jì)算。 時(shí)間復(fù)

    2024年01月19日
    瀏覽(21)
  • flink 1.18 sql gateway /sql gateway jdbc

    flink 1.18 sql gateway /sql gateway jdbc

    一 sql gateway 注意 之所以直接啟動(dòng)gateway 能知道yarn session 主要還是隱藏的配置文件,但是配置文件可以被覆蓋,多個(gè)session 保留最新的applicationid 1 安裝flink (略) 2 啟動(dòng)sql-gatway(sql-gateway 通過(guò)官網(wǎng)介紹只能運(yùn)行在session 任務(wù)中) 2-1 啟動(dòng)gateway 之前先啟動(dòng)一個(gè)flink session ./bin/yarn-

    2024年01月16日
    瀏覽(41)
  • 【Linux】在centos快速搭建K8S1.18集群

    【Linux】在centos快速搭建K8S1.18集群

    使用 kubeadm 創(chuàng)建集群幫助文檔 如果您需要以下幾點(diǎn),該工具是很好的選擇:kubeadm 一種簡(jiǎn)單的方法,讓你嘗試 Kubernetes,可能是第一次。 現(xiàn)有用戶(hù)自動(dòng)設(shè)置群集并測(cè)試其應(yīng)用程序的一種方式。 其他生態(tài)系統(tǒng)和/或安裝程序工具中的構(gòu)建塊,具有更大的 范圍。 一臺(tái)或多臺(tái)機(jī)器,

    2024年04月29日
    瀏覽(28)
  • mormot2 筆記(二) Http服務(wù)的簡(jiǎn)單搭建

    mormot2框架中有個(gè)THttpServer類(lèi),它有一個(gè)Router屬性,定義如下: Router是添加路由的入口點(diǎn),它有和http協(xié)議對(duì)應(yīng)的get, post, put, delete等方法,這些方法可以添加路由,下面常用的get方法定義。 這里我們不能像js中koa2類(lèi)似的寫(xiě)法,除非我們寫(xiě)個(gè)helper類(lèi),給TUriRouter加個(gè)方法,然后就

    2024年02月12日
    瀏覽(14)
  • 100天精通Python丨辦公效率篇 —— 07、Python自動(dòng)化操作 office-excel(讀寫(xiě)、增刪改查、分組統(tǒng)計(jì))
  • CDH 6.3.2集成flink 1.18 zookeeper版本不匹配Flink-yarn啟動(dòng)失敗

    CDH 6.3.2集成flink 1.18 zookeeper版本不匹配Flink-yarn啟動(dòng)失敗

    CDH 6.3.2集成flink 1.18 zookeeper版本不匹配Flink-yarn不能正常啟動(dòng),而在CHD Web頁(yè)面,flink日志報(bào)錯(cuò)提示不明確,不能定位具體錯(cuò)誤。CM WEB啟動(dòng)失敗錯(cuò)誤日志如下圖所示: CM查看完成錯(cuò)誤日志 CM管理頁(yè)面查看異常日志,始終不能定位啟動(dòng)異常原因,此時(shí)查看flink詳情啟動(dòng)日志,日志文

    2024年02月03日
    瀏覽(20)
  • Kubernetes - CentOS7搭建k8s_v1.18集群高可用(kubeadm/二進(jìn)制包部署方式)實(shí)測(cè)配置驗(yàn)證手冊(cè)

    Kubernetes - CentOS7搭建k8s_v1.18集群高可用(kubeadm/二進(jìn)制包部署方式)實(shí)測(cè)配置驗(yàn)證手冊(cè)

    一、Kubernetes—k8s是什么 Kubernetes 這個(gè)名字源于希臘語(yǔ),意為“舵手“或”飛行員\\\"。 Kubernetes,簡(jiǎn)稱(chēng)K8s,中間有8個(gè)字符用8代替縮寫(xiě)。 Google于2014年開(kāi)源項(xiàng)目,為容器化應(yīng)用提供集群和管理的開(kāi)源工具,Kubernetes目標(biāo)是讓部署容器化的應(yīng)用簡(jiǎn)單并且高效,提供了應(yīng)用部署,規(guī)劃,更

    2024年04月27日
    瀏覽(25)
  • SpringBoot_第七章(讀寫(xiě)分離)

    SpringBoot_第七章(讀寫(xiě)分離)

    目錄 1:MybatisPlus(讀寫(xiě)分離) 1.1:首先創(chuàng)建三個(gè)數(shù)據(jù)庫(kù)1主2從 1.2:代碼實(shí)例 1.3:優(yōu)缺點(diǎn)分析 2:SpringBoot路由數(shù)據(jù)源(讀寫(xiě)分離) 2.1:實(shí)現(xiàn)原理 2.2:代碼實(shí)現(xiàn) 2.3:測(cè)試代碼? 2.4:優(yōu)缺點(diǎn)分析 這里列舉了兩種讀寫(xiě)分離實(shí)現(xiàn)方案,如下 表名是user表 1:導(dǎo)入pom 2:配置spring的主從

    2024年02月06日
    瀏覽(18)
  • 2023-07-18力扣每日一題-有點(diǎn)難

    鏈接: 1851. 包含每個(gè)查詢(xún)的最小區(qū)間 題意: 給定一個(gè)區(qū)間二維數(shù)組,有 N個(gè)[L,R] 區(qū)間(閉區(qū)間) 給定一組查詢(xún),有 M個(gè)正整數(shù) ,求 存在于區(qū)間數(shù)組中的最小 R-L+1 滿(mǎn)足 L=M[i]=R 解: 本來(lái) 看標(biāo)簽有個(gè)掃描線(xiàn),想寫(xiě)個(gè)差分,然后排序查詢(xún)整O(1)查詢(xún)的,沒(méi)寫(xiě)出來(lái)QWQ,也不知道有沒(méi)

    2024年02月16日
    瀏覽(29)
  • 07-1_Qt 5.9 C++開(kāi)發(fā)指南_文件系統(tǒng)及文件讀寫(xiě)_文本文件讀寫(xiě)(使用 QTextStream 進(jìn)行文件讀寫(xiě)更為方便)

    07-1_Qt 5.9 C++開(kāi)發(fā)指南_文件系統(tǒng)及文件讀寫(xiě)_文本文件讀寫(xiě)(使用 QTextStream 進(jìn)行文件讀寫(xiě)更為方便)

    文本文件是指以純文本格式存儲(chǔ)的文件,例如用 Qt Creator 編寫(xiě)的 C++程序的頭文件 (.h 文件)和源程序文件 (.cpp 文件)。HTML 和 XML 文件也是純文本文件,只是其讀取之后需要對(duì)內(nèi)容進(jìn)行解析之后再顯示。 Qt 提供了兩種讀寫(xiě)純文本文件的基本方法, 一種是用 QFile 類(lèi)的 IODevice 讀寫(xiě)

    2024年02月13日
    瀏覽(20)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包