⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiofp documentation - a worked example of using the tiopf.htm

📁 tiOPF 面向对象的数据库持久层持久层开发的框架
💻 HTM
📖 第 1 页 / 共 5 页
字号:
ContactMgr_TestData.sql. Enter the SQL as shown below, then run the script, or 
run each statement one at the time by selecting it and pressing F8.</P><PRE>/*****************************************************************
  Create the contact manager test data
*/
insert into Person values
   ( 1, 'Peter', 'Hinrichsen', 'Mr.', 'P.W.', 'The founder of the tiOPF project' ) ;
insert into adrs values
   ( 2, 1, 'Street', '23 Victoria Pde.', 'Collingwood', 'VIC', '3066', 'Australia' ) ;
insert into adrs values
   ( 3, 1, 'Postal', 'PO Box 429', 'Abbotsford', 'VIC', '3067', 'Australia' ) ;
insert into EAdrs values
   ( 4, 1, 'EMail', 'peter_hinrichsen@techinsite.com.au' ) ;
insert into EAdrs values
   ( 5, 1, 'Mobile', '0418 108 353' ) ;
insert into EAdrs values
   ( 6, 1, 'Fax', '+61 3 9419 1682' ) ;
commit ;</PRE>
<P>Test that the data has been correctly inserted by running the following 
queries in the tiSQLEditor:</P><PRE>select * from person ;
select * from adrs ;
select * from eadrs ;</PRE>
<P>The results of the third select statement are shown below:</P>
<P><IMG height=173 
src="tiOFP Documentation - A worked example of using the tiOPF_files/6_AWorkedExampleOfUsingTheTIOPF_clip_image001_0008.gif" 
width=410></P>
<P>Now that we have created a database, and inserted some test data we can look 
at the various strategies available for mapping the database into the business 
objects we created.</P>
<H2>Alternative BOM – database mapping strategies</H2>
<P>There are three strategies available for mapping objects to a relational 
database:</P>
<OL>
  <LI>Hard code the SQL into the application, and use the Visitor framework to 
  map the SQL to the objects. This is implemented by linking in the unit 
  Adrs_SrvHardCodeSQL.pas 
  <LI>Use the tiSQLManager application to maintain the SQL outside the 
  application. This has the advantage of decoupling the SQL from the 
  application, but the disadvantage of forcing you to add the tiSQLManager 
  tables to the database. (This will be corrected when we have an XML 
  persistence layer available) 
  <LI>Set up mappings between the objects and tables, properties and columns and 
  let the persistence framework generate the SQL for you. This can be 
  implemented by linking in Adrs_SrvAutoGenSQL.pas (This strategy is under 
  construction, and this example will work in most classes. There are some 
  problems with BLOBS, and the way the mappings are defined is a little messy) 
  </LI></OL>
<P>In summary, you must link in one and only one of the three unit files. The 
best way of achieving this is to create a dependencies unit that will provide a 
central point for determining the strategy to be used. Create a new unit called 
ContactMgr_Dependencies, which looks like this:</P><PRE>Unit ContactMgr_Dependencies;
Interface
Uses
  ContactMgr_BOM,
//ContactMgr_SvrHardCode
//ContactMgr_SvrSQLMgr
  ContactMgr_SvrAutoMap
 ;
Implementation
End.</PRE>
<P>As you can see, the above example is using the auto-map option, but switching 
options is as simple as un-commenting the relevant unit (assuming you have 
created these units in the first place!). You now need to add this to the 
project source. Select Project...View Source and modify the source so it looks 
like the listing below:</P><PRE>Program ContactMgr;
Uses
  tiLog,
  tiPersist,
  Forms,
  FMain In 'FMain.pas' {frmMain},
  ContactMgr_BOM In 'ContactMgr_BOM.pas',
  ContactMgr_Cli In 'ContactMgr_Cli.pas',
  ContactMgr_Tst In 'ContactMgr_Tst.pas',
  FContactMgr_Person In ' FContactMgr_Person.pas' {TFormContactMgr_Person},
  ContactMgr_Dependencies In 'ContactMgr_Dependencies.pas';
{$R *.RES}
Begin
  SetupLogForClient;
  Application.Initialize;
  gTIPerMgr.LoadPersistenceFramework;
  Application.CreateForm(TfrmMain, frmMain);
  Application.Run;
  gTIPerMgr.UnLoadPersistenceFramework;
End.</PRE>
<H2>Hard code the SQL</H2>
<P>Create a new unit called ContactMgr_SvrHardCode.pas</P>
<P>Add tiPtnVisSQL to the visitor and type the interface as shown below:</P>
<P>Hit Ctrl+Shift+C to fill in the implementation</P>
<P>Add ContactMgr_BOM, tiPersist and tiPtnVisPerObj to the implementation uses 
clause.</P><PRE>unit ContactMgr_SvrHardCode;
interface
uses
  tiPtnVisSQL
 ;
type
  TVisPeopleReadHardCode = class( TVisOwnedQrySelect )
  protected
    function AcceptVisitor : boolean ; override ;
    procedure Init ; override ;
    procedure SetupParams ; override ;
    procedure MapRowToObject ; override ;
  end ;
  
implementation
uses
   ContactMgr_BOM
  ,tiPersist
  ,tiPtnVisPerObj
  ;</PRE>
<P>In the implementation of AcceptVisitor, type result := Visited is TPerson</P><PRE>{ TVisPeopleReadHardCode }
function TVisPeopleReadHardCode.AcceptVisitor: boolean;
begin
  result := ( Visited is TPeople ) ;
end;</PRE>
<P>In the implementation of Init, enter the SQL to select all the people. This 
can be simplified by entering SELECT * FROM PEOPLE in the tiSQLEditor and 
executing the query. There is then an option to copy the SQL to the clipboard 
with the delimeters and line breaks added. The result is shown below:</P><PRE>procedure TVisPeopleReadHardCode.Init;
begin
  Query.SQL.Text :=
    'select ' +
    '  OID ' +
    ' ,FIRST_NAME ' +
    ' ,LAST_NAME ' +
    ' ,TITLE ' +
    ' ,INITIALS ' +
    ' ,NOTES ' +
    'from ' +
    '  person ' ;
end;</PRE>
<P>Enter the MapRowToObject implementation as shown below. This is made easier 
by executing the SELECT SQL, then using the SQL | MapRowToObject to copy the 
necessary code to the clipboard and pasting it into Delphi. The code looks like 
this as it is copied to the clipboard.</P><PRE>procedure TVisEAdrsReadHardCode.MapRowToObject;
var
  lData : T&lt;Class type&gt; ;
begin
  lData := T&lt;Class type&gt;.Create ;
  lData.Oid.AssignFromTiQuery(Query);
  lData.FirstName := Query.FieldAsString[ 'FIRST_NAME' ] ;
  lData.LastName := Query.FieldAsString[ 'LAST_NAME' ] ;
  lData.Title := Query.FieldAsString[ 'TITLE' ] ;
  lData.Initials := Query.FieldAsString[ 'INITIALS' ] ;
  lData.Notes := Query.FieldAsString[ 'NOTES' ] ;
  lData.ObjectState := posClean ;
  TPerVisList( Visited ).Add( lData ) ;
end;</PRE>
<P>All you have to do is replace the T&lt;Class type&gt; place holders with 
TPerson and the result looks like this:</P><PRE>procedure TVisPeopleReadHardCode.MapRowToObject;
var
  lData : TPerson ;
begin
  lData := TPerson.Create ;
  lData.Oid.AssignFromTiQuery(Query);
  lData.FirstName := Query.FieldAsString[ 'FIRST_NAME' ] ;
  lData.LastName := Query.FieldAsString[ 'LAST_NAME' ] ;
  lData.Title := Query.FieldAsString[ 'TITLE' ] ;
  lData.Initials := Query.FieldAsString[ 'INITIALS' ] ;
  lData.Notes := Query.FieldAsString[ 'NOTES' ] ;
  lData.ObjectState := posClean ;
  TPerVisList( Visited ).Add( lData ) ;
end;</PRE>
<P>SetupParams has no code in the implementation:</P><PRE>procedure TVisPeopleReadHardCode.SetupParams;
begin
  // Do nothing
end;</PRE>
<P>Register the visitor with the persistence framework like this:</P><PRE>initialization
  gTIPerMgr.RegReadVisitor( TVisPeopleReadHardCode ) ;
end.</PRE>
<P>The 12 Visitors that comprise the full implementation of the Contact Manager 
persistence visitors, implemented by hard coding SQL can be found in 
ContactMgr_SrvHardCode.pas.</P>
<P>Use the tiSQLManager</P>
<P>Create the tiSQLManager tables</P><PRE>create domain domain_oid as integer not null ;
create table Next_OID ( oid domain_oid ) ;
insert into next_oid ( oid ) values ( 100000 ) ;
create domain domain_sql as blob sub_type 1 ;
create domain domain_str20 as varchar( 20 ) not null ;
create domain domain_str50 as varchar( 50 ) not null ;
create domain domain_str100 as varchar( 100 ) ;
create domain domain_integer as integer default 0 not null ;
create domain domain_boolean as char( 1 ) default 'F' check ( value in ( 'T', 'F' )) ;

/* SQLMan_Group table */
create table sqlman_group
   ( oid domain_oid,
   group_name domain_str50,
   disp_order domain_integer,
   primary key ( oid )) ;

/* SQLMan_SQL table */
   create table sqlman_sql
   ( oid domain_oid,
   group_oid domain_oid,
   disp_order domain_integer,
   query_version domain_integer,
   query_name domain_str50,
   query_description domain_sql,
   query_locked domain_boolean,
   test_include domain_boolean,
   sql domain_sql,
   primary key ( oid )) ;
   
/* SQLMan_Param Table */
   create table sqlman_param
   ( oid domain_oid,
   sql_oid domain_oid,
   disp_order domain_integer,
   param_name domain_str20,
   param_type domain_str20,
   param_value domain_str50,
   param_isnull domain_boolean,
   primary key ( oid )) ;

/* SQLMan_Interface Table */
   create table sqlman_interface
   ( oid domain_oid,
   sql_oid domain_oid,
   disp_order domain_integer,
   field_name domain_str20,
   field_type domain_str20,
   primary key ( oid )) ;

/* Add ref integ */
   alter table SQLMan_SQL
   add foreign key ( Group_OID ) references SQLMan_Group ( OID ) ;
alter table SQLMan_Param
   add foreign key ( SQL_OID ) references SQLMan_SQL ( OID ) ;
alter table SQLMan_Interface
   add foreign key ( SQL_OID ) references SQLMan_SQL ( OID ) ;
/* Add unique constraint */
   create unique index I_SQLMan_Group
   on SQLMan_Group
   ( Group_Name ) ;
create unique index I_SQLMan_SQL
   on SQLMan_SQL
   ( Query_Name ) ;
create unique index I_SQLMan_Param
   on SQLMan_Param
   ( SQL_OID, Param_Name ) ;
create unique index I_SQLMan_Interface
   on SQLMan_Interface
   ( SQL_OID, Field_Name ) ;
insert into sqlman_group
   ( oid, group_name, disp_order ) values
   ( 1, 'System', 0 ) ;
insert into sqlman_group values ( 2, 'Queries', 0 ) ;
commit ;</PRE>
<P>Write the tiSQLManager Visitors</P><PRE>Unit ContactMgr_SvrSQLMgr;
interface
   uses
   tiPtnVisSQL
   ;
type
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Read visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleReadSQLMgr = class( TVisQrySelect )
protected
  function AcceptVisitor : boolean ; override ;
  procedure Init ; override ;
  procedure SetupParams ; override ;
  procedure MapRowToObject ; override ;
end ;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Delete visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleDeleteSQLMgr = class( TVisQryUpdate )
protected
  function AcceptVisitor : boolean ; override ;
  procedure Init ; override ;
  procedure SetupParams ; override ;
end ;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Update visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleUpdateSQLMgr = class( TVisQryUpdate )
protected
  function AcceptVisitor : boolean ; override ;
  procedure Init ; override ;
  procedure SetupParams ; override ;
end ;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Create visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleCreateSQLMgr = class( TVisQryUpdate )
protected
  function AcceptVisitor : boolean ; override ;
  procedure Init ; override ;
  procedure SetupParams ; override ;
end ;

implemen

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -