转到Lazarus后发现缺少适合的三层控件,尝试过国产商业及网上的开源三层控件,但存在或多或少的问题,始终找不到满意的三层控件(特别是linux aarch64下),决定趁2022年最后一天,开发一个基于RealThinClient SDK简单实用的lazarus三层控件(参考网上的相关代码)。
服务端网络通信组件和数据库组件决定三层控件性能和稳定可靠的关键所在,delphi很多三层使用强大的mORMot作为网络通信控件,还有部分使用RealThinClient SDK,如全能中间件等,RTC的特点为是轻量/稳定,还有,RealThinClient SDK比mORMot使用更简单方便,也比较容易实现我想要的功能,最重要的是能在linux(包括amr64/x86_64等CPU)和windows下使用,准备使用RTC作为我的三层控件的网络通信组件。服务端用数据库组件测试了unidac、zeosdbo和lazarus自带的SQLDB等,zeosdbo和lazarus自带的SQLDB在不同平台需要各种数据库驱动,部署难度大;unidac支持直连方式与数据库连接,不需要数据库驱动,部署简单方便,linux服务端首选unidac作为服务端的数据库控件。
数据库可以选择MSSQL2000、MySQL和PostgreSQL,中间件已适配这3种数据库,其中MSSQL为支持分页,表需添加ID字段。如果服务端在Linux运行,建议使用MySQL和PostgreSQL,因unidac不支持linux aarch64 for SQLite,所以数据库没选择SQLite。
服务端使用RealThinClient SDK和UNIDAC,客户端使用RealThinClient SDK和RealThinClient SDK的内存表(TRTCMemdataset),客户端封装了TQFRemoteConnection、TQFRemoteTable、TQFRemoteQuery和TQFRemoteStoredProc等4个控件,其中TQFRemoteTable支持分页功能,如果没分页功能,在数据量大时性能下降严重,影响用户体验,2023-1-20增加自动保存变更后的数据。TQFRemoteConnection包含从服务端返回使用Snowflake方法生成的ID,取服务端时间和上传/下载文件(没有进度提示)功能,近日,将QFRemoteDataSet封装为可视控件,使用更简单方便。
这个三层控件功能相对简单,只适合lazarus使用,但非常实用,编写的应用软件能在windows和国产信创操作系统(linux)及CPU运行,使用时只需在uses添加QFRemoteDataSet单元,按下面的方法使用就可以,使用起来挺简单的。
QQ:315175176 秋风
1.直接引用QFRemoteDataSet单元时的代码:
procedure TForm1.FormCreate(Sender: TObject); var myinifile:Tinifile; begin MYIniFile := TIniFile.Create(Extractfilepath(Paramstr(0)) + 'config.ini'); Edit1.Text:=MyIniFile.readstring('服务器', 'IP', '127.0.0.1'); Edit2.Text:= MyIniFile.readstring('服务器', '端口', '81'); Edit5.Text:=MyIniFile.readstring('服务器', '加密密钥', ''); MYIniFile.Free; QFConnect1:=TQFRemoteConnection.Create; QFConnect1.server_ip:=edit1.Text; QFConnect1.server_port:=edit2.text; QFConnect1.Compression:=true; //压缩 QFConnect1.SecureKey:=Edit5.text;//加密key QFTable:=TQFRemoteTable.Create(self); QFTable.DataPagination:=True; QFTable.Connection:=QFConnect1; DataSource1.DataSet:=QFTable; QFTable.TableName:='混凝土试块数据'; QFTable.KeyFields:='报告编号,序号'; end; procedure TForm1.Button2Click(Sender: TObject); begin FTimeUsed := GetTickCount; if QFConnect1=nil then begin QFConnect1:=TQFRemoteConnection.Create;//创建连接 QFConnect1.server_ip:=edit1.Text; //设置服务端IP QFConnect1.server_port:=edit2.text;//设置服务端端口 end; if QFTable=nil then begin QFTable:=TQFRemoteTable.Create(nil);//创建Table QFTable.Connection:=QFConnect1; //指定Table的connection QFTable.TableName:='混凝土试块数据'; QFTable.KeyFields:='报告编号,序号'; end; QFTable.DataPagination:=CheckBox1.Checked;//数据分页 DataSource1.DataSet:=QFTable; QFTable.open; Label2.Caption:= '记录数:'+QFTable.RecordCount.ToString+' 第'+QFTable.CurPage.ToString+'页/共'+QFTable.PageNoMax.ToString+'页'+' '+IntToStr(GetTickCount - FTimeUsed) + '毫秒'; end;
2.用控件时的代码:
procedure TForm1.FormCreate(Sender: TObject); var myinifile:Tinifile; begin MYIniFile := TIniFile.Create(Extractfilepath(Paramstr(0)) + 'config.ini'); Edit1.Text:=MyIniFile.readstring('服务器', 'IP', '127.0.0.1'); Edit2.Text:= MyIniFile.readstring('服务器', '端口', '81'); Edit5.Text:=MyIniFile.readstring('服务器', '加密密钥', ''); MYIniFile.Free; QFRemoteConnection1.SecureKey:=Edit5.Text; QFRemoteConnection1.Server_ip:=Edit1.Text; QFRemoteConnection1.Server_port:=Edit2.Text; end; procedure TForm1.Button2Click(Sender: TObject); begin FTimeUsed := GetTickCount; QFRemoteTable1.DataPagination:=CheckBox1.Checked;//数据分页 DataSource1.DataSet:=QFRemoteTable1; QFRemoteTable1.open; Label2.Caption:= '记录数:'+QFRemoteTable1.RecordCount.ToString+' 第'+QFRemoteTable1.CurPage.ToString+'页/共'+QFRemoteTable1.PageNoMax.ToString+'页'+' '+IntToStr(GetTickCount - FTimeUsed) + '毫秒'; end;
将QFRemoteDataSet封装为可视控件:
windows服务端:
linux服务端:
客户端在windows运行时的截图:
客户端在银河麒麟linux arm64运行截图:
QFRemoteDataSet下载链接:通过百度网盘分享的文件:QFRemote...
https://pan.baidu.com/s/16TGs5LWYHBEpoeBM-K1-BA?pwd=G876
提取码:G876