DaaS 服务端 Java二次开发指南-Lesson 4:获取并使用Manager和DAO

659 阅读5分钟

回到目录

Lesson 4:获取并使用Manager和DAO

每个XML中定义的模型都会生成对应的Manager和DAO,用于提供基础的功能。(参见 <DaaS 概要与建模> 中 ‘JAVA源代码目录介绍’ 一节)

在 Manager Bean 中获取 Manager 和 DAO

在每个ManagerBean中提供了快捷方式获取模型对应的Manager。

例如bank.xml中有定义“change_request”, 那么得到它的Manager如下:

changeRequestManagerOf(ctx)....

下图为使用ChangeRequestManager创建一条新记录的示例。

获取DAO的方式类似,代码为:

changeRequestDaoOf(ctx)

下为增加了DAO后的代码示例:

public Object getThenUserManagerAndDao(BankUserContext ctx) throws Exception {
    ChangeRequest r1 = changeRequestManagerOf(ctx)
        .createChangeRequest(ctx, "name", ChangeRequestType.DEPOSITE, "P000001");
    ChangeRequest r2 = changeRequestDaoOf(ctx)
        .load(r1.getId(), ChangeRequestTokens.withoutLists());
    return CollectionUtils.toList(r1,r2);
}

使用‘gradle bootRun’, 编译运行; 再使用postMan访问以上接口,截图如下:

在 Manager Bean 以外的地方获取Manager和DAO

Manager Bean里的xxxManagerOf(ctx)是一个快捷的包装。
在某些情况下,例如工具方法类中,需要获取某个Manager和DAO,可以直接使用UserContext:

userContext.getManagerGroup().getChangeRequestManager()... userContext.getDAOGroup().getChangeRequestDAO()...

使用Manager

xxxManager的方法,在得到它后就可以调用了。

您可以查看源代码获得所有的细节。这里简要介绍一下几类API。

上面的例子中,可以看到返回的结果,是两个JSON对象的数组,其中每个对象里展开了一些对象:

这个展示了 Manager 中的createXXX() 方法和DAO中的load()方法。

Create方法

createXXX() 方法的参数,第一个仍然是UserContext,然后是按照XML中定义的顺序出现的必须的参数。 例如上例中定义的模型为:

那么"name", "request_type","plateform"是需要输入的 (参见<DaaS 概要与建模>),其他属性:create_time, remote_ip 则不会。所以看到的调用方法为:

changeRequestManagerOf(ctx).createChangeRequest(ctx,"name",ChangeRequestType.DEPOSITE,"P000001");

Save 方法

Save类的方法包括updatexxx..; ...save....等,请查看您手上的每次生成的源代码 “public interface XXXManager” 中的定义,如本例中的:

updatexxx() 方法是更新属性值的,用于‘编辑即保存’的场景; internalSave系列方法则是保存整个对象的,用于‘提交再保存’的场景;

Load 方法

loadXXXX方法的定义及实现,请查看您手中生成的源代码。load方法很简单

Token

在save/load方法中,可以看到一个参数 tokens,或者叫‘options’:

Token 是用来控制‘范围’的。

每个模型都会有对应的Tokens类生成,方便使用。例如:

// 只涉及ChangeRequest对象本身
Map<String, Object> tok1 = ChangeRequestTokens.empty();
// 涉及ChangeRequest对象本身,以及被他直接引用的对象;
Map<String, Object> tok2 = ChangeRequestTokens.withoutLists();	
// 涉及ChangeRequest对象本身,以及被他直接引用的RequestType对象
Map<String, Object> tok3 = ChangeRequestTokens.start().withRequestType().done();

例如load中使用tok3,则它不会加载platform,而只会加载requestType。

transfer方法

transfer方法用于在不同的‘引用’对象中切换。

例如本例中的 requestType,当我们想从一个type,切换到另外一个type时,就可以调用:

ChangeRequest r1 = ...
changeRequestManagerOf(ctx).transferToAnotherRequestType(
        ctx,
        r1.getId(), // 要做transfer的对象ID
        ChangeRequestType.WITHDRAW); // 新的引用对象的ID

delete 方法

delete方法需要说明的是,默认不做真实的数据库删除,只是将被删除对象中,直接引用的其他对象断开(置为null)。

成员操作方法

默认的,为模型的‘子对象列表’提供了快捷操作。包括 add、remove,udpdate

其中,‘Transaction’,‘NameChangeEvent’和‘AccountChange’都是挂在‘changeRequest’下的子对象。

使用DAO

默认会生成"XXXJDBCTemplateDAO.java",它实现了接口“XXXDAO”(是的,你可以在你手中已经生成的代码中看到)。

CRUD 方法

CRUD类的方法,通过简单的名字即可看出接口的功能。例如

这些就不详细讲了,源代码也很简洁。

find 方法

find类的方法是对‘查询’功能的一种封装,提供简洁的调用,例如:

  • 注意这里又出现了 ‘options’。 此处的options是指‘find’的范围。因此它返回的结果不会作用于加载的对象本身,而只是和查询相关的部分。 例如:

      changeRequestDaoOf(ctx).findChangeRequestByRequestType(
          ChangeRequestType.CHANGE_NAME,
          PlatformTokens.start()
          	.searchChangeRequestListWith(ChangeRequest.CREATE_TIME_PROPERTY, "between","2012-12-21~2019-12-21")
          	.sortChangeRequestListWith(ChangeRequest.REQUEST_TYPE_PROPERTY, "asc")
          	.done()
      );
    

它生成的查询语句在日志中可以看到:

SQL为:

select * from change_request_data
where request_type = 'CHANGE_NAME' 
and create_time between '2012-12-21' and '2019-12-21'
order by request_type asc;

这里的 3,4 行就是tokens的作用。

token 在find类接口中的使用,还在不断的更新中。DAO中还提供了基础的JDBC接口 queryList:

public SmartList<ChangeRequest> queryList(String sql, Object ... parmeters);

这个接口就非常简单了,自己写SQL,构造parameters即可。

enhance类方法

以本例中的‘ChangeRequest’为例:会有以下几种enhance类的接口:

  • public void collectAndEnhance(BaseEntity ownerEntity);

    这个接口用于,在用户持有本对象的上级对象时,加载上级对象中引用的本对象。

  • public SmartList loadOurTransactionList(BankUserContext userContext, List us, Map<String,Object> options) throws Exception;

  • public SmartList loadOurNameChangeEventList(BankUserContext userContext, List us, Map<String,Object> options) throws Exception;

  • public SmartList loadOurAccountChangeList(BankUserContext userContext, List us, Map<String,Object> options) throws Exception;

    这几个接口用于从一个list中加载所有下级对象。

  • public ChangeRequest present(ChangeRequest changeRequest,Map<String, Object> options)

    这个接口用于按照tokens增强子对象。默认的行为是:出现在token中的子对象(仅限于直接相关的一层范围)被加载出来,没有出现在token中的则不加载。

其他方法

其他还有count类接口,clone,requestCandidate等。这些代码的实现都很简单,在源代码中可以查看细节,功能也和名称一致,以后再详述。

回到目录