红鱼儿

ClientAsTemplate用法

kbmMW提供了TkbmMWClientQuery查询组件,作为kbmMW开发者都知道,这是一个内存数据集,基于服务端的查询服务(Query Service),可以直接执行sql得取想要的记录,因为是内存表,可以直接增、删、改记录,并利用Resolve方法提交修改到服务器,同时,也支持事务,利用kbmMWClientTransactionResolve组件,在事务中一次提交多个数据集。

利用ClientQuery组件,就可以轻松将原来的两层应用,如基于ADO设计的系统,移置到kbmMW多层架构上来,方便快捷,无缝升级旧有系统,这不得不佩服kbmMW作者的功力,做出如此易用的kbmMW多层架构。

如果你还不知kbmMWClientQuery的用法,可以学习以前一的文章,在这里:kbmMW实现sql查询。在这篇文章里,没有提及到kbmMWClientQuery.Client属性,也实现了查询,那这个Client有什么作用呢?这正是本文要解释的内容。

kbmMWClientQuery.Client是TkbmMWCustomSimpleClient类型,TkbmMWSimpleClient是继承自TkbmMWCustomSimpleClient的组件,其作用是向服务端发送请求,并可取得服务端返回的结果。更具体说,就是调用服务端实现的方法,这是kbmMW框架中最基础的类。在窑洞洞主的系列文章中第一个例子就是介绍如何实现服务端方法并通过SimpleClient来调用,不清楚可以先去看看,先理解SimpleClient的作用。

当理解了SimpleClient的作用,对于kbmMWClientQuery.Client属性就不难理解,实际上kbmMWClientQuery就是通过Client属性,调用服务端查询服务的方法,以执行sql取得返回结果集。那问题来了,当我们不设置Client属性,kbmMWClientQuery又是怎么发送的查询请求呢?通过源码,就会明白,不管kbmMWClientQuery.Client属性是否为nil,都会自己在内部建立一个SimpleClient实例。当ClientQuery.Client为nil,则通过这个实例与服务端通信,执行服务端查询服务的各种内置方法。如果为kbmMWClientQuery.Client指定了一个SimpleClient,kbmMWClientQuery就会使用指定的SimpleClient与服务端通信,为什么要这样设计呢?其目的就是多个ClientQuery共享一个SimpleClient。而共享一个SimpleClient的好处就是开发者可以为SimpleClient设置好需要传递给服务端的数据,而不用每次都做重复处理,这又是哪些数据呢?比如:用户名与密码,还有就是自己特定的数据。

说了这么多,我想已经说清了kbmMWClientQuery.Client的作用,并且如何使用他。但这都是在主线程中去实现,没有问题,如果在多线程中使用ClientQuery,并且共享一个SimpleClient,那问题就来了,SimpleClient不是线程安全的,我们不能这么干,否则你的应用就不稳定了,会出现各种地址错误。很多kbmMW初级开发者会因为这个问题认为kbmMW框架不稳定。

解决这个问题,就是利用ClientAsTemplate属性,将他设置为True,通过源码,我们会看到,如果ClientAsTemplate为True,当ClientQuery获取SimpleClient时,会使用内部的SimpleClient,同时复制Client属性对应的实例内容到内部的SimpleClient。然后再用内部的SimpleClient调用服务端的方法。

上面所说的逻辑在ClientQuery.GetActiveClient实现代码中,当ClientQuery要执行服务端方法时,就是通过这个方法取得SimpleClient,然后用他去调用服务端方法。可以进一步参考ClientQuery.GetMetaData等方法,这些方法中,可以清晰的看到使用GetActiveClient方法取得SimpleClient。

 

posted on 2018-08-21 22:35  红鱼儿  阅读(584)  评论(0编辑  收藏  举报