Delphi中DataSource、ClientDataSe
一、DataSource的两个主要作用:
1、连接数据集和数据感知控件
2、连接两个存在数据关系的数据集(比如数据要一起联动,或者两个数据集本身就是主从关系)
这时从数据集的DataSource要设置为指向主数据集的DataSource组件
二、两个数据集设置主从方式(针对ADO控件,因为FireDAC的Dataset没有datasource属性)
假设有两个表,teacher和student表,结构及数据如下,可以看出,一个老师有多个学生,student表通过teacherid与teacher表连接(也可以把两个表看成是主从关系)。
teacher表:
ID TeacherName
1 alex
2 miley
3 joana
4 BBQ
Student表:
ID StudentName TeacherID
1 john 1
2 stephen 1
3 ooo 1
4 ABC 2
5 EFG 2
6 kathy 3
7 steph 4
1、参数方式
两个数据集需要联动时,可以在SQL语句中使用参数的方式。
(1)dataset1的语句是select * from teacher
(2)datasource1的dataset设置为dataset1
(3)dataset2的语句是select * from student where teacherid = :id (:id说明了需要接收id参数)
(4)dataset2的datasource属性设置为datasource1
这样就完成了联动设置,当dataset1的记录变化时,由于dataset2的datasource是datasource1,所以能够接收到dataset1传过来的新的id参数。因此dataset2的记录也会根据dataset1的id不同而变化。
2、设置范围方式(巢状数据)
这种方式不需要写代码,通过组件配置就可以实现。
(1)dataset1的语句是select * from teacher
(2)datasource1的dataset设置为dataset1
(3)dataset2的语句是select * from student (这里不需要接收任何参数)
(4)dataset2的datasource属性设置为datasource1
(5)点击dataset2的masterfields的省略号,在弹出设置框中设置关联关系
这样dataset1和dataset2的主从关系就已经设置好了。
三、FireDAC设置主从关系
详细英文页面:http://docwiki.embarcadero.com/RADStudio/Rio/en/Master-Detail_Relationship_(M/D)
FireDAC设置主从也有两种方式(实际上对应ADO的两种方式):
1、基于参数的方式。和ADO的参数方式差不多,可用于 TFDQuery 或者 TFDStoredProc(只能用在这两个控件上),主从是通过重新查询实现。
2、基于范围的方式。可以用于所有FireDAC的数据集控件,它是通过设置范围的方式来实现,同时需要设置从表的IndexFieldName。(这个索引表示数据按哪个列来排列)
Feature Parameter-based Range-based
The detail query returns a limited number of records. +
The detail records are fresh. +
Reduced traffic and DBMS workload on each master change. +
The cached updates preserved on the master change. +
Works in offline mode. +
Supports Centralized Cached Updates with propagation +
同时,FireDAC也有两种缓存更新方式:
1、非集中式更新。主从表各自保存各自的缓存
2、集中式的更新。主从表共享同一份更新日志,可以做到更好的控制,实现级联更新,以及实现自增值等。(个人觉得,集中式的更新,共享更新日志,是ClientDataset可以对接主表,形成巢状数据库的关键,因此巢状数据在这种方式下才能形成,不管是ADO还是FireDAC)
1、参数方式:
与ADO相同,区别在第(4)步,是将从表的MasterSource指向主表(ADO中是Datasource)。同时,可以选择是否设置MasterField字段,如果设置了就按照设置,不设置就按参数同名的字段。
2、范围方式:
前面步骤与ADO的方式相同,从第(4)步开始:
(4)dataset2的MasterSource属性设置为datasource1
(5)点击dataset2的masterfields的省略号,在弹出设置框中设置关联关系。同时设置IndexFieldNames字段(重要)
注:在从表里,MasterSource、MasterField里,指的都是主表,即关联到主表的datasource、主表的联接字段。
四、ClientDataSet主要作用:
1、作为独立的、与数据库无关的、全功能的内存数据集,实现大部分数据存储和操作功能,这时它就相当于单层数据库
2、作为多层数据库的客户端,连接本层或者中间层的provider控件(如果连接的不是本层的provider,则需要用DCOMConnect去连中间层),再由provider连接DataSet
3、存储具有主从关系的巢状数据集
五、ClientDataSet设置巢状数据库
用ClientDataSet设置巢状数据库,前提是ado组件(或其它table类组件)已经构建好了主从关系(如第二步第2点所述。
(1)放置TProvider组件,Dataset属性设置成dataset1(即主从关系的主表)
(2)将clientdataset1的providername设置成provider1,将active设置为true,可以看到,clientdataseet1已经将主从关系表数据都取回来了。其中主表数据正常显示,从表数据用一个字段表示,字段名一般为从表组件名,在这个示例中是adodataset2
(3)双击clientdataset1,弹出字段编辑器,然后点add all fields,这样就自动生成了所有字段。在单层的程序中,这一步是必要的,因为没有应用服务的connection提供信息,所以如果不手工增加一下字段信息的话,第(4)步就无法选择也无法输入巢状字段名,会报无效的字段。
(4)将clientdataset2的datafield字段设置为clientdataset1的那个包含从表数据的字段,在本例中是adodataset2字段。这时巢状数据关系就已经设置好了。