在kbmmw 5.02.1 中,加入了ORM 的功能(這裡可能和其他語言的定義不完全一樣),我們就簡單的認為
它就是一個類與資料庫的轉換吧。今天就先介紹一下如何通過kbmmw 的ORM 功能,實作類與資料庫的互相
轉換和操作。
前提條件:delphi 10.2.1
kbmmw 5.02.1
unidac 7.0.2
啟動haosql for sqlserver2008 管理器,啟動資料庫。

打開delphi ,建立一個标準的工程,放置如圖的幾個控件
設定uniconnection1 連接配接sql server 2008 資料庫
ok
加入幾個必要的單元,并設定好初始化代碼。
現在建立一個單元,定義一個聯系人類,并加入對應的标注資訊
好了,我們傳回主窗體, 加入對應的代碼,我們先建立對應的表。
編譯運作,點建立庫 按鈕,顯示建表成功。
我們看看背後發生了什麼?首先我們先在 sql monitor 裡面,看看背景做了什麼?
通過sql monitor, 我們可以非常清晰的看見,kbmmw 先在次資料庫中查詢是否有這個表,如果沒有這個表,則根據Tcontact 中定義的
字段來生成對應的SQL 語句,執行這個SQL,在資料庫中生成對應的表。
資料庫中生産的完全沒問題。我們下一步生成一些資料,看看是否正常。
生成資料代碼
看看背景都有那些sql.實際上這個Persist 是更新和插入,如果更新失敗就插入。
看看資料庫裡面的生成資料的效果。
完全正确。
下面看一下如何通過ORM 查詢資料。
kbmmw orm 查詢資料有三種方式。
// Query mode controls what syntax to use for queries.
// mwoqmMW (default) use kbmMW's SQL syntax and automatically
// rewrite the query to match supported databases.
// mwoqmNative provides the query string without alterations to the
// database.
// mwoqmMixed default use kbmMW's SQL syntax with automatic rewrite
// unless the first character in the query statement is #
TkbmMWORMQueryMode = (mwoqmMW,mwoqmNative,mwoqmMixed);
預設使用kbmmw 自身的SQL 文法,并自動轉換成對應的資料庫文法
第二種是直接使用目标資料庫的文法
第三種是混合方式, 如果查詢首字母不是# 的話,就用kbmmw 自身的sql 文法。
我們使用混合模式查詢
或者
運作結果
背景SQL 亦是如此
我們來查詢單條資料,單挑資料有兩種查詢方式
一種是SQL 方式,一種ORM 方式
先介紹一下sql 方式
運作效果
使用kbmw ORM 方式查詢
修改資料庫
結果也一切正常
看看背景發生了什麼?
資料庫是否儲存正确?
沒問題,太爽了。
順便添加一下删除的代碼
清除全部的資料
删除建的表
終于寫完了。
大家對上面kbmmw 标注肯定很頭疼,第一要記很多标注名,第二不能筆誤,這個确實麻煩,
好消息是,作者已經把自動生産這些标注列入計劃,期待後面的版本能直接自動生産,那就友善多了。
在沒有自動聲場之前,請大家參照一下說明,自己手工處理。
// ORM attribute syntax
// ====================
//
// kbmMW_Table - Define a table.
// Must be used on classes.
// Define a table named person.
// [kbmMW_Table('name:person')]
// Define 2 ascending indexes i_fieldname, and i_anotherfieldname on the field fieldname and anotherfieldname.
// [kbmMW_Table('name:person, index:fieldname, index:anotherfieldname...
// Define an ascending index named i1, on the field name
// [kbmMW_Table('name:person, index:{name:i1,field:name},...
// Define a descending index named i1, on the field name
// [kbmMW_Table('name:person, index:{name:i1,field:name,descending:true},...
// Define a compound unique index named i2, on the fields name and age. Name field part is descending.
// [kbmMW_Table('name:person, index:{name:i2,unique:true,fields:[{name:name,descending:true},{name:age}]
// kbmMW_Field - Define fields in a table.
// Must be used on properties within a class if they are to be persisted.
// Define a field that will be persisted. Its type will be decided for
// from the property type. String type fields will have a size of 50.
// Table field name will be the same as the property name.
// [kbmMW_Field]
// Define a field that will be persisted. It will accept unicode data of max 50 characters.
// It will have the same name as the property.
// [kbmMW_Field(ftWideString,50)]
// Define a field named id, and make it primary key. It will be automatically populated bu the generator shortGuid.
// [kbmMW_Field('name:id, primary:true, generator:shortGuid',ftString,40)]
// property ID:kbmMWNullable<string> read FID write FID;
// These generators exists:
// GUID - Returns a GUID formatted as a regular GUID {123e4567-e89b-12d3-a456-426655440000}
// SHORTGUID - Returns a short GUID where braces and dashes are missing: 123e4567e89b12d3a456426655440000
// SEQUENCE - Returns next unique number from a sequence. Provide name of sequencer in sequence property
// and optional sequencestart property (not supported by all databases!)
// DATETIME - Returns a date time value, formatted according to the dateFormat property.
// Define a field named id, and make it primary key. It will be populated by a sequence generator.
// Since no sequencer was given, one is automatically generated named s_tablename_fieldname
// [kbmMW_Field('name:id, primary:true, generator:sequence',ftInteger)]
// property ID:kbmMWNullable<integer> read FID write FID;
// Define a field named id, and make it primary key. It will be populated by sequence generator SEQ, starting from value 10.
// (not all databases supports sequencers with a defined start!)
// [kbmMW_Field('name:id, primary:true, generator:sequence, seqneuce:SEQ1, sequenceStart:10',ftInteger)]
// Define a field named id, and make it primary key. It will be populated automatically by the database.
// (not all databases support auto increment type fields!)
// [kbmMW_Field('name:id, primary:true',ftAutoInc)]
// Define a field named datetime containing date/time values as Delphi local time values.
// [kbmMW_Field('name:datetime',ftDateTime)]
// property DateTime:TkbmMWDateTime read FDateTime write FDateTime;
// Define a field named datetime containing date/time values as Delphi UTC values.
// [kbmMW_Field('name:datetime, dateFormat:UTC',ftDateTime)]
// Define a field named datetime containing date/time values as Unix local time millisecs since EPOC.
// [kbmMW_Field('name:datetime, dateFormat:LOCALSINCEEPOCHMS',ftInt64)]
// Define a field named datetime containing date/time values as Unix UTC time millisecs since EPOC.
// [kbmMW_Field('name:datetime, dateFormat:UTCSINCEEPOCHMS',ftInt64)]
// Define a field named datetime containing date/time values as Unix local time secs since EPOC.
// [kbmMW_Field('name:datetime, dateFormat:LOCALSINCEEPOCH',ftInt64)]
// Define a field named datetime containing date/time values as Unix UTC time secs since EPOC.
// [kbmMW_Field('name:datetime, dateFormat:UTCSINCEEPOCH',ftInt64)]
// Define a field named datetime containing date/time values as ISO8601 formatted string.
// [kbmMW_Field('name:datetime, dateFormat:ISO8601',ftString,50)]
// Define a field named datetime containing date/time values as RFC1123 formatted string.
// [kbmMW_Field('name:datetime, dateFormat:RFC1123',ftString,50)]
// Define a field named datetime containing date/time values as NCSA formatted string.
// [kbmMW_Field('name:datetime, dateFormat:NCSA',ftString,50)]
// kbmMW_Null - Specify NULL conversion.
// (This attribute is also used for object marshalling).
// If, for example, a property is of type integer, the property is not directly able to indicate a NULL state since
// all values of an integer are considered non NULL values.
// However its possible to define a specific value to be interpreted as NULL.
// Eg.
// [kbmMW_Field('name:somefield',ftInteger)]
// [kbmMW_Null(-1)]
// property MyProperty:integer read FMyProperty write FMyProperty;
// This will define that the value -1 must be interpreted as NULL when storing and retrieving data
// from the database.
// kbmMW_NotNull - Indicate that the property must never contain the NULL value (either interpreted via the kbmMW_Null attribute or actual).
// [kbmMW_NotNull]
// property MyProperty:kbmMWNullable<integer> read FMyProperty write FMyProperty;