| 6.BM??2012-01-05 13:46:50by SeaCat 在Aurora框架中,可通过一个BM配置文件同时实现数据的查询,新增,修改等操作。但是,在实际应用中,往往会碰到这样的情况:执行查询时需要10个字段,并需要join其他的一些表,而执行插入时只需要6个字段;或者,一个BM在大多数查询时都适用,但在某种场合下又要加上额外的限制条件,而查询结果中的字段又是完全相同的。如果为这些应用场景都开发一个单独的BM,势必会有很多重复的成分,相同的配置散布在多个文件里,不仅开发效率低,也会带来维护的麻烦。 Aurora为BM提供了一种继承机制,与java语言中的继承类似,一个BM可以继承自另一个BM,从而自动获取父BM所有或部分配置,并可设置自己特有的属性。 与Java语言中的全盘继承所不同的是,BM可以通过设置继承模式,来有选择地继承父BM中的各种对象。例如,父BM中定义了10个字段,子BM中可以选择只继承其中的3个。下面分别说明BM的两种继承模式。 在引用模式中,子BM必须显示地定义哪些对象是希望从父BM中继承过来的。例如: “test/emp_for_lov.bm”<bm:model xmlns:bm="http://www.aurora-framework.org/schema/bm" alias="t2" extend="test.emp" extendMode="reference"> <bm:fields> <bm:field name="empno"/> <bm:field name="employee_name"/> </bm:fields> </bm:model> 这里,该BM通过extend="test.emp"属性,声明从test.emp继承而来,并通过extendMode="reference"属性,声明继承模式为引用模式。在fields部分,定义了两个field,并且只设置了name属性。这意味着,该BM将从test.emp继承empno,employee_name这两个指定的字段。字段上的属性,如dataType,databaseType等也将一并继承过来。test.emp的其他字段,由于没有在子BM中声明,就不会出现在子BM中。 查看通过该BM生成的查询SQL,可以看到: SELECT t1.empno,t1.ename AS employee_name,dept.dname AS department_name FROM emp t1 LEFT OUTER JOIN dept dept ON t1.deptno = dept.deptno 由于子BM只声明了两个字段,所以select的字段部分只有两个。但是,父BM中定义的relations及ref-fields依然在生效。下面将详细解释其中的原理。 BM中有很多集合对象,如fields是field的集合,ref-fields是ref-field的集合,query-fields是query-field的集合,等等。在reference模式下,对于父BM的集合对象,处理规则如下:
我们再看一个例子,上面的子BM中,我们首先设置name="empno"的physicalName属性,改为另外一个字段名,再增加一个名为salary的field,然后在ref-fields部分设置一个父BM没有设置过的字段,最后再增加一个data-filter: “test/emp_for_lov2.bm”<bm:model xmlns:bm="http://www.aurora-framework.org/schema/bm" alias="t2" extend="test.emp" extendMode="reference"> <bm:fields> <bm:field name="empno" physicalName="empno1_that_not_exists"/> <bm:field name="employee_name"/> <bm:field name="salary" expression="trunc(sal)"/> </bm:fields> <bm:ref-fields> <bm:ref-field name="new_dname" relationName="dept" sourceField="dname"/> </bm:ref-fields> <bm:data-filters> <bm:data-filter expression="mrg is not null"/> </bm:data-filters> </bm:model> 然后查看生成的查询SQL: SELECT t2.empno1_that_not_exists AS empno,t2.ename AS employee_name,trunc(sal) AS salary,dept.dname AS new_dname FROM EMP t2 LEFT OUTER JOIN dept dept ON t2.deptno = dept.deptno WHERE mrg is not null 由于empno字段的physicalName属性在子BM中被重新定义,所以生成的SQL中以子BM中设置的字段名为准。salary字段是子BM新定义的,父BM中没有该字段,也会出现在生成的SQL中。由于ref-fields集合在子类中被设置,所以会只出现子BM设置了的ref-fields;而relations集合没有设置,所以relations部分完全继承父BM。由于子BM额外定义了data-filters,所以生成的SQL中多了一个where条件。 在BM中,设置extendMode="override"来设置继承模式为重载模式。这种模式与Java语言的继承模式类似,子BM将继承父BM的所有设置,子BM设置的同名属性、节点将覆盖父BM的设置。实例: “test/emp_for_lov3.bm”<bm:model xmlns:bm="http://www.aurora-framework.org/schema/bm" alias="t2" extend="test.emp" extendMode="override" needAccessControl="false"> <bm:fields> <bm:field name="empno" physicalName="empno1_that_not_exists"/> <bm:field name="employee_name"/> </bm:fields> <bm:ref-fields> <bm:ref-field name="new_dname" relationName="dept" sourceField="dname"/> </bm:ref-fields> <bm:data-filters> <bm:data-filter expression="mrg is not null"/> </bm:data-filters> </bm:model> 除了extendMode属性,其他与emp_for_lov2完全一致。对应的查询SQL: SELECT t2.empno1_that_not_exists AS empno,t2.ename AS employee_name,trunc(sal) AS salary,t2.job,t2.mgr,t2.hiredate,t2.deptno,t2.sal,t2.comm,dept.dname AS new_dname,dept.dname AS department_name FROM EMP t2 LEFT OUTER JOIN dept dept ON t2.deptno = dept.deptno WHERE mrg is not null 由于override模式下,所有设置都会从父BM继承,所以生成的SQL中包含test.emp定义过的所有字段。由于子BM对empno字段重新设置了physicalName属性,所以该字段对应的SQL以子BM为准。与前例相同,在子BM中添加的设置,如名为salary的field,以及data-filter,都会生效。子BM定义的ref-field,由于名称不一样,所以会与父BM定义的ref-field合并,同时出现在SQL中。 在override模式下,对于父BM的集合对象,处理规则如下:
所谓同名节点,是子BM和父BM中,同一集合下,具有相同name属性的节点,例如fields下面中具有相同name的field。如果父节点和子节点都设置了相同的属性,那么以子节点的为准,如前面例子中,empno字段中的physicalName属性。如果父节点设置了某属性而子节点没有设置,则自动从父节点继承此属性。如果子节点设置了而父节点没有设置,一样以子节点为准。 这些规则同样也适用于BM的根节点:model。例如,父BM中设置了<bm:model alias="t1" >,子BM中设置了<bm:model alias="t2" >,那么最终的alias将是t2。 以下就各种典型的应用场合,分析子BM应该如何设置。
Demo Attachments |
Comments
1 Responses to the article