5.??BM?????

2012-01-05 13:44:31by SeaCat

在BM中使用Feature

Feature示例:Standard Who

Aurora可以看做是一个面向Feature的框架。所谓Feature,就是指可以重复使用的某种功能或特征。我们先来看一个例子。在企业应用中,经常需要在数据中记录更新信息,例如记录的创建人,创建时间,最后更新人,最后更新时间等。反应到数据库表结构上,就是大多数业务数据表都会有created_by,creation_date,last_updated_by,last_update_date等这样几个字段。每条记录在创建或更新的时候,都应该维护这几个字段。比如,创建记录时设置created_by等于当前登录用户的id,creation_date等于系统日期。

如果用单纯的O/R Mapping的思路去建模,这样特性很难做出合理的可重用设计。如果将这个特性封装在父类中,要求每个有此特性的业务实体都继承指定的父类。对于Java这样的单继承语言来说,一定会遇到某些业务实体必需从其他的父类派生,或者某些业务实体需要从父类派生,但又不需要这种特性的情况。这时,在子类coding就不可避免。对于Hibenate这样的O/R Mapping工具来说,如果出现这种具有一定共性的需求,对于应用开发人员来说,除非对Hibernate的源代码非常熟悉,否则就很难在短时间内扩展Hibernate,去实现这种特性。

Aurora的BM提供了一种基于配置的,声明式的功能扩展机制。以前面的emp.bm为例,我们在配置文件中增加一段feature配置:

<?xml version="1.0" encoding="UTF-8"?>
<bm:model xmlns:bm="http://www.aurora-framework.org/schema/bm" xmlns:f="aurora.database.features" alias="e" baseTable="EMP" needAccessControl="false">
    <bm:fields>
        <bm:field name="empno" databaseType="BIGINT" datatype="java.lang.Long" insertExpression="(select max(empno)+1 from emp)"/>
        <bm:field name="employee_name" databaseType="VARCHAR" datatype="java.lang.String" physicalName="ename"/>
        <bm:field name="job" databaseType="BIGINT" datatype="java.lang.String"/>
        <bm:field name="mgr" databaseType="BIGINT" datatype="java.lang.Long"/>
        <bm:field name="hiredate" databaseType="DATE" datatype="java.sql.Date"/>
        <bm:field name="deptno" databaseType="BIGINT" datatype="java.lang.Long"/>
        <bm:field name="sal" databaseType="FLOAT" datatype="java.lang.Long" updateExpression="trunc(${@sal})"/>
        <bm:field name="comm" databaseType="FLOAT" datatype="java.lang.Long"/>
        <bm:field name="last_updated_by" databaseType="BIGINT" datatype="java.lang.Long" forInsert="false" forceUpdate="true" updateExpression="${/session/@user_id}"/>
    </bm:fields>
    <bm:primary-key>
        <bm:pk-field name="empno"/>
    </bm:primary-key>
    <bm:relations>
        <bm:relation name="dept" joinType="LEFT OUTER" refModel="test.dept">
            <bm:reference foreignField="deptno" localField="deptno"/>
        </bm:relation>
    </bm:relations>
    <bm:ref-fields>
        <bm:ref-field name="department_name" relationName="dept" sourceField="dname"/>
    </bm:ref-fields>
    <bm:features>
        <f:standard-who/>
    </bm:features>
</bm:model>	    
	    

在BM的最后,声明了features部分,并在其下设置了一个名为standard-who的feature。增加了这个设置以后,再看通过BM生成的insert,update语句,可以看到自动多出了对前面几个追溯字段的处理:

INSERT INTO EMP 
	( ...,CREATED_BY,CREATION_DATE,LAST_UPDATED_BY,LAST_UPDATE_DATE) 
VALUES 
	( ..., ${/session/@user_id},sysdate,${/session/@user_id},sysdate)	    
	    

UPDATE EMP e
SET .... , e.LAST_UPDATED_BY=${/session/@user_id},e.LAST_UPDATE_DATE=sysdate
WHERE e.empno = ${@empno}	    
	    

如果表中的standard who字段的名字与缺省的不一致,可通过standard-who标记的属性进行配置:

<f:standard-who createdByField="create_user_id" creationDateField="create_time" lastUpdatedByField="updated_user_id" lastUpdatedDateField="update_time" userIdPath="/session/@user_login_id"/>
	    

Aurora框架提供了一种机制,可以在配置文件中放入任意xml标记,并将这个标记和某一个或某些java class关联在一起。进而,这些java class会在框架处理数据的过程中,选择合适的切入点,介入处理过程,对中间数据进行加工、转换,从而实现各种可扩展的特性。对于上面的例子来说,实现standard-who标签的java class,在生成实际SQL之前接管控制,自动在BM中添加4个standard who字段。这样,生成的insert,update语句中,就会多出standard who字段的处理。

对于这个简单的例子,虽然说也可以要求开发人员在自己的BM中都手工加上这四个字段,但有可能会有人失误,少放置了某个字段,或者将某个字段的名称,数据类型拼写错误。以standard-who标签的方式来配置,由于只涉及一个配置点,出错的几率大大减少。更重要的是,这种具有普遍性的业务需求的实现,将集中于一处,更有利于维护。如果今后实现standard who的机制发生改变,例如不是直接存在业务数据表中,而是单独存在一个另外的表,那只需要开发一个新的java class,按新的数据结构去生成SQL语句,并将其与standard-who标签关联在一起就可以,不用去修改已经存在的所有BM。

Aurora内建Feature介绍

Aurora框架自带了一些feature,下面将逐一介绍。请注意,虽然看起来这是Aurora框架“内建”的功能,但它们并不是框架的一级成员,而是一种“插件”。它们和用户自行开发的feature完全一样,是通过配置的方式来集成到Aurora框架中的。

数据多语言
Lookup代码
Oracle sequence
标记式删除
Demo
    Attachments

      Comments

      1 Responses to the article
      1. [email protected] 留言于:2017年06月06日 13:38
        好东西。
      发表评论