运行环境: WIN 10 X64
delphi 10.2.2
kbmmw 5.05.11
Firefox 58.0.2
今天使用最新的kbmmw 版本做一个基于ORM的纯数据库访问的REST 服务器。
老规矩,先建一个工程,然后把对应的控件仍上去(控件党),设置对应的一些属性,
主窗体代码非常简单,就是建立ORM,开启服务器
unit mainp; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, kbmMWServer, kbmMWCustomTransport, kbmMWCustomConnectionPool, kbmMWORM, // 为了支持 ORM, 此单元需要手工加入 kbmMWCustomSQLMetaData, kbmMWSQLiteMetaData, kbmMWSQLRewriter, kbmMWSQLite, kbmMWFilePool, kbmMWHTTPSysServerTransport; type TForm1 = class(TForm) kbmMWServer1: TkbmMWServer; Button1: TButton; kbmMWHTTPSysServerTransport1: TkbmMWHTTPSysServerTransport; kbmMWFilePool1: TkbmMWFilePool; kbmMWSQLiteConnectionPool1: TkbmMWSQLiteConnectionPool; kbmMWSQLiteSQLRewriter1: TkbmMWSQLiteSQLRewriter; kbmMWSQLiteMetaData1: TkbmMWSQLiteMetaData; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } FxalionORM:TkbmMWORM; // 定义ORM public { Public declarations } property xalionORM:TkbmMWORM read FxalionORM; // 方便其他单元使用 end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin kbmmwserver1.Active:=True; end; procedure TForm1.FormCreate(Sender: TObject); begin fxalionORM:=TkbmMWORM.Create; // 创建ORm fxalionORM.OpenDatabase(kbmMWSQLiteConnectionPool1); // 与数据库绑定 kbmmwserver1.AutoRegisterServices; end; procedure TForm1.FormDestroy(Sender: TObject); begin FxalionORM.CloseDatabase; // 关闭数据库 FxalionORM.Free; // 释放 end; end.
新建一个服务单元,定义对应的代码
unit Unit2; {$I kbmMW.inc} interface uses SysUtils, Classes, Generics.Collections, Vcl.Imaging.jpeg, Vcl.Graphics, DB, kbmMWNullable, kbmMWSecurity, kbmMWServer, kbmMWServiceUtils, kbmMWGlobal, kbmMWCustomHTTPSmartService, kbmMWRTTI, kbmMWObjectMarshal, kbmMWORM, kbmMWSmartServiceUtils; type // ORM style access to the biolife table // We could have used traditional kbmMW query components // too if we wanted. [kbmMW_Table('name:animals')] // 定义实体表 TAnimals = class private Fname:kbmMWNullable<string>; Fsize:kbmMWNullable; Fweight:kbmMWNullable ; Farea:kbmMWNullable<string>; Fbmp:kbmMWNullable ; public [kbmMW_Field('name:"name"',ftString,10)] property name:kbmMWNullable<string> read Fname write Fname; [kbmMW_Field('name:"size"',ftInteger)] property size:kbmMWNullable read Fsize write Fsize; [kbmMW_Field('name:"weight"',ftFloat)] property weight:kbmMWNullable read Fweight write Fweight; [kbmMW_Field('name:"area"',ftMemo)] property area:kbmMWNullable<string> read Farea write Farea; [kbmMW_Field('name:"bmp"',ftGraphic)] [kbmMW_Element([mwefInline])] property bmp:kbmMWNullable read Fbmp write Fbmp; end; [kbmMW_VirtualTable(Tanimals,[mwomtProperty],[mwomvtPublic])] // 这是基于上面实体表的虚表 TAnimalsNoImage = class private Fname:kbmMWNullable<string>; Fsize:kbmMWNullable ; Fweight:kbmMWNullable ; Farea:kbmMWNullable<string>; public property name:kbmMWNullable<string> read Fname write Fname; property size:kbmMWNullable read Fsize write Fsize; property weight:kbmMWNullable read Fweight write Fweight; property area:kbmMWNullable<string> read Farea write Farea; end; [kbmMW_Service('name:animals')] [kbmMW_Rest('path:/animals')] TkbmMWCustomSmartService3 = class(TkbmMWCustomHTTPSmartService) private { Private declarations } protected { Protected declarations } public { Public declarations } [kbmMW_Rest('method:get, path:helloworld')] function HelloWorld:string; [kbmMW_Rest('method:get, path:all')] function Getall:TObjectList ; [kbmMW_Rest('method:get, path:"name/{no}"')] function Getname([kbmMW_Rest('value:"{no}"')] const Aname:string):TAnimalsNoImage; [kbmMW_Rest('method:get, path:"image/{no}", responseMimeType:"image/jpeg"')] function GetImage([kbmMW_Rest('value:"{no}"')] const Aname:string):TkbmMWBytes; end; implementation uses kbmMWExceptions, mainp; {$R *.dfm} // Service definitions. //--------------------- function TkbmMWCustomSmartService3.HelloWorld:string; begin Result:='Hello world'; end; function TkbmMWCustomSmartService3.Getall:TObjectList ; begin Result:=form1.xalionORM.QueryList ; end; function TkbmMWCustomSmartService3.Getname(const Aname:string):TAnimalsNoImage; begin Result:=form1.xalionORM.Query (['name'],[Aname]); end; function TkbmMWCustomSmartService3.GetImage(const Aname:string):TkbmMWBytes; var bl:Tanimals; jpg:TJPEGImage; bmp:TBitmap; ms:TkbmMWMemoryStream; begin Result:=nil; bl:=form1.xalionORM.Query (['name'],[Aname]); if bl<>nil then begin try // Convert from ftGraphics format to JPG. // ftGraphics format includes 8 byte header that must be skipped to // get to the BMP data. jpg:=TJPEGImage.Create; try bmp:=Tbitmap.Create; try bl.bmp.Value.Position:=8; bmp.LoadFromStream(bl.bmp.Value); jpg.Assign(bmp); ms:=TkbmMWMemoryStream.Create; try jpg.SaveToStream(ms); ms.Position:=0; Result:=TkbmMWPlatformMarshal.Stream2Bytes(ms); finally ms.Free; end; finally bmp.Free; end; finally jpg.Free; end; finally bl.Free; end; end; end; initialization TkbmMWRTTI.EnableRTTI([TkbmMWCustomSmartService3, Tanimals, TObjectList , TAnimalsNoImage, TObjectList ]); kbmMWRegisterKnownClasses([Tanimals, TObjectList , TAnimalsNoImage, TObjectList ]); end.
运行。
在浏览器里面输入
http://localhost/animals/all
运行结果为
数据库实际内容为:
也可以根据name 单独显示一条数据
最后通过name 来显示图像
实在是太方便了。
2018年6月17日
5.6 里面也可以使用ON 方式操作
function TkbmMWCustomSmartService3.Getalljson: string; var myon:TkbmMWONCustomObject; myjs: TkbmMWJSONStreamer; begin myon:= form1.xalionORM.QueryON; myjs:=TkbmMWJSONStreamer.Create; try result:=myjs.SaveToUTF16String(myon); finally myjs.Free; end; end;