Synopse mORMot框架样例学习03 - NamedPipe Client-Server
前边的例01和例02分别展示了静态服务器及嵌入式SQLite3服务器的实现方法,例03是命名管道客户端-服务器,例01中用JSON文件存储数据(按我的理解,每一个SQLRecord就是一个表格,在存储的时候多个表格应该需要多个JSON文件取存储),例02中使用SQLite3数据库存储,只需要一个.db3数据库文件就能存放所有的SQLRecord(表格),例03中实现了客户端-服务器的通讯,客户端的数据需要传递到服务器去处理.
先看看服务器是怎么运行的,例03主单元Unit2.pas实现了命名管道服务器,在代码中看比较方便,省略了部分代码,只看主要的部分:
unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, // 下方是mORMot单元 SynCommons, mORMot, mORMotSQLite3, SynSQLite3Static, StdCtrls, SampleData; type TForm1 = class(TForm) { ...(省略) } public Model: TSQLModel; { 声明SQL操作模型 } Server: TSQLRestServerDB; { 服务器的声明 } end; { ...(省略) } implementation {$R *.dfm} { ...(省略) } procedure TForm1.FormCreate(Sender: TObject); begin Model := CreateSampleModel; { 窗口创建的时候初始化数据库操作模型 } Server := TSQLRestServerDB.Create(Model, ChangeFileExt(ExeVersion.ProgramFileName, '.db3')); { 初始化一个Rest服务器,这里和样例2是一样的 } Server.CreateMissingTables; { 根据模型Model创建必须的表格(也就是SampleData单元定义的类) } Server.ExportServerNamedPipe('03'); { 创建命名管道,名字为03,客户端初始化的时候必须和此名称一致才能进行进程间通讯 } end; { ...(省略) } end.
然后是客户端部分,这一次我想把SampleData单元进行简单的改造下,添加一个用户信息类,用于存储用户名和密码,这样我们在初始化数据库的时候会有2个表格SampleRecord和UserInfo,还是看代码的注释进行说明:
unit SampleData; interface uses SynCommons, mORMot; type TSQLSampleRecord = class(TSQLRecord) { ...省略 } end; { 我们再添加一个类,用于记录用户名和密码 } TSQLUserInfo = class(TSQLRecord) private fUserName: RawUTF8; fPassWord: RawUTF8; fRemark: TSQLSampleRecord; published property UserName: RawUTF8 read fUserName write fUserName; property PassWord: RawUTF8 read fPassWord write fPassWord; property Remark: TSQLSampleRecord read fRemark write fRemark; end; function CreateSampleModel: TSQLModel; implementation function CreateSampleModel: TSQLModel; begin result := TSQLModel.Create([TSQLSampleRecord, TSQLUserInfo{ 创建模型的时候要加上我们新定义的类 }]); end; end.
客户端同样需要进行一些改造,我们需要输入用户名和密码信息,然后一同添加到数据库中,改造后是这个样子的:

在这里,客户端的工程单元必须创建客户端命名管道,并且管道的名字要与服务端保持一致:
{ 创建与服务端一致的客户端命名管道,以便与服务端通信 } Form1.Database := TSQLRestClientURINamedPipe.Create(Form1.Model, '03');
主单元Unit1.pas实现代码如下:
unit Unit1; interface uses {$ifdef MSWINDOWS} Windows, Messages, Graphics, {$endif} Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls, SynCommons, SynTable, mORMot, SampleData; type { ...省略 } implementation {$ifdef FPC} {$R *.lfm} {$else} {$R *.dfm} {$endif} procedure TForm1.FormCreate(Sender: TObject); begin Model := CreateSampleModel; { 调用后SampleRecord和UserInfo同时对数据库中对应的2个表进行映射 } end; procedure TForm1.AddButtonClick(Sender: TObject); var Rec: TSQLSampleRecord; UserRec: TSQLUserInfo; { 声明用户信息类 } begin Rec := TSQLSampleRecord.Create; UserRec := TSQLUserInfo.Create; { 创建实例 } try Rec.Name := StringToUTF8(NameEdit.Text); Rec.Question := StringToUTF8(QuestionMemo.Text); Rec.Log := StringToUTF8('added ' + NameEdit.Text + ' ' + QuestionMemo.Text); if Database.Add(Rec, true) = 0 then ShowMessage('Error adding the data') else begin MemoLog.Lines.Add('Name: ' + NameEdit.Text + ';' + 'Question: ' + QuestionMemo.Text + ';'); NameEdit.Text := ''; QuestionMemo.Text := ''; NameEdit.SetFocus; end; { 把用户名和密码写进数据库 } UserRec.UserName := StringToUTF8(UserNameEdit.Text); UserRec.PassWord := StringToUTF8(PassWordEdit.Text); if DataBase.Add(UserRec, true) = 0 then ShowMessage('Error adding the data') else begin UserNameEdit.Clear; PassWordEdit.Clear; end; finally Rec.Free; UserRec.Free; end; end; { ...省略 } end.
需要先启动服务端,然后再启动客户端,同样写入3组记录,然后用sqliteadmin看看数据库的情况:

数据库存储情况如下:

可以看到,和预想的情况一样,例02和例03不管是在嵌入式数据库还是客户端-服务器的设计,除了DataBase初始化的部分有少许不同,其他代码可以原封不动,感觉很是方便.到这里基本上摸清了例01-例03样例的目的,就是最基础的ORM操作,和不同数据存储的方式使用,对照文档看一下,确实如文档所说,作者并没有夸大框架的功能,但是总感觉不太习惯作者的英语表达方式,不动手实践,有的东西光看文档的确能让人感到迷糊,继续努力学习.

浙公网安备 33010602011771号