Mach-II新手指南(下)
读入和操作数据
1. 引言
大家好,欢迎回来。本文紧接着教程的上集。如果你还没看过上集的话,建议先看一下。
自从我写了教程上集后,发生了很多事。期间我开发了我的第一个真正意义上的面向对象的程序。但那个程序没有使用mach-ii或其他任何一种框架结构。
有一样东西我在上集中没有强调(实际上我发现我一点没有提到它),那就是:Mach-II框架“是为了帮助软件开发和维护使用面向对象风格”(mach-ii.info如是说)。还句话说,要想使用和掌握mach-ii框架你必须对现象对象的编程有所了解。
记得我曾经在没有看到框架带来的任何好处的时候坚持使用它,“我们一定要相信一直建处下去付出终有回报”。在完成那个面向对象的项目后,我终于可以明确的告诉你,继续下去一定会有收获的!看到使用mach-ii框架给项目带来的好处后,我认为这种回报将是双倍的(起码是增加很多)。
然而到现在,面向对象编程还没被我们讨论。我已经受到对上集教程的很多积极的反馈信息,但也有不少批评意见。其中一个说,我太过专注于mach-ii.xml配置文件了却没有认真讲讲 bean的原理。虽然我承认了解bean原理很重要,但是bean不是mach-ii特有的产物,mach-ii.xml文件才是mach-ii最特别的地方。
2. 小小的重复
我们来复习一下上集的学习内容。
•在mach-ii.xml配置文件里,我们定义了一个默认事件;
•默认事件调用一个页面;
•页面下显示内容是在配置文件的page-view里定义的;
•页面文件包含一个用来定义新事件的表单;
•这个新事件将表单传递来的值安装到bean组件;
•这个新事件还通告了一个listener,用来将bean作为变量传递给CRUD组件。
现在你还记得我在上集结束的时候所给的变量吗?
不使用其他任何ado,这里的解决方案是:
<event-handler event="message.create" access="public">
<event-bean name="message" type="MyGuestbook.model.message.message" />
<notify listener="messageListener" method="createMessage" />
<view-page name="mainTemplate" />
</event-handler>
我刚肯定你已经自己完成这一步了吧。
3. 我们该前往何处?
第一个明确要做的事是获取之前在我们的页面上提交的留言。 所以我们需要查询数据库里之前插入的信息,同时进一步了解mach-ii获取显示信息的方式。
在上集我们使用CRUD组件向数据库放入一个留言。但是我还说过
CRUD每次只处理一条数据库记录。所以为了查询多条记录,我们需要创建一个新的组件(也被称为通道(gateway))。
写下下面的代码,取名为messageGateway.cfc,保存到model/message/ directory。
<
cfcomponent displayname="Message Gateway" hint="I am a data gateway to messages">
<cffunction name="init" access="public"
returntype="MyGuestbook.model.message.messageGateway" output="false">
<cfargument name="dsn" type="string" required="true" />
<cfset variables.dsn = arguments.dsn />
<cfreturn this />
</cffunction>
<cffunction name="findMessages" access="public" returntype="query" output="false">
<cfset var findMessages = 0 />
<cfquery name="findMessages" datasource="#variables.dsn#">
SELECT *
FROM guestbook
ORDER BY id
</cfquery>
<cfreturn findMessages />
</cffunction>
</cfcomponent>
我们开始做比较熟悉的工作,可以回顾一下上集讲的CRUD里的init方法。findMessage方法里面嵌入了SELECT语句。
与CRUD中的类似的,init方法是listener调用该通道的线索。所有我们来做之前做过的事,实际上我们是在同一个listener里完成它的。因此,打开messageListener.cfc,作如下修改:
<cfcomponent extends="MachII.framework.Listener" displayname="Message Listener" hint="I am the listener for
messages">
<cffunction name="configure" access="public" returntype="void" output="true" displayname="Listener Constructor"
hint="I initialize this listener as part of the framework startup.">
<cfscript>
var dsn = getAppManager().getPropertyManager().getProperty("dsn");
variables.messageCRUD = CreateObject("component", "MyGuestbook.model.message.messageCRUD").init(dsn,
"MyGuestbook");
variables.messageGateway = CreateObject("component",
"MyGuestbook.model.message.messageGateway").init(dsn, "MyGuestbook");
</cfscript>
</cffunction>
<cffunction name="createMessage" access="public" returntype="void" output="false" displayname="Create Message"
hint="I cause message to be created from the current event object.">
<cfargument name="event" type="MachII.framework.Event" required="yes" displayname="Event" hint="I am the current
event" />
<cfset var message = arguments.event.getArg("message") />
<cfset variables.messageCRUD.create(message) />
</cffunction>
<cffunction name="getAllMessages" access="public" returntype="query" output="false" displayname="Get All
Messages" hint="I return a query containing all of the messages.">
<cfreturn variables.messageGateway.findMessages() />
</cffunction>
</cfcomponent>
在这个listener里增加的代码本身就可以说明问题。
当这个listener在mach-ii.xml文件里注册好后,可以在showMain句柄里使用新方法直接调用它。
<event-handler event="showMain" access="public">
<notify listener="messageListener" method="getAllMessages" resultKey="request.qry_messages" />
<view-page name="mainTemplate" />
</event-handler>
打开views/mainTemplate.cfm文件,在提交留言的表单上方添加以下代码:
<
cfoutput query="request.qry_messages">
<hr>
<strong>From:</strong> <a href="mailto:#email#">#name#</a>
#LSDateFormat(date,"dd mmmm yyyy")#<br>
<strong>Message:</strong><br>
#message#<br>
</cfoutput>
这样我们需要显示的所有的信息都将显示在这个主页上(我打赌你预想的要比这个难).但是现在你可以笑得畅快了-试着发送另一条留言吧.
我的确可以在这样做之前就可以预见结果了.:
<event-handler event="showMain" access="public">
<notify listener="messageListener" method="getAllMessages" resultKey="request.qry_messages" />
<view-page name="mainTemplate" />
</event-handler>
<event-handler event="message.create" access="public">
<event-bean name="message" type="MyGuestbook.model.message.message" />
<notify listener="messageListener" method="createMessage" />
<view-page name="mainTemplate" />
</event-handler>
这两个事件将显示同一个页面,不过只有第一个会调用listener的getAllMessages()方法.只要加一个对listener的调用到事件句柄就解决这个问题.然而,似乎有什么地方不对劲儿.我发现””正确的”解决方法了,想想看,过一秒钟再告诉你.
好的,我回来了.还在为此困惑吗?这里有解决的办法.到现在我们将加一个相同的调用给第二个事件句柄然后回来在第三篇教程解决这个问题,那时候我们打算讨论过滤器和插件.所以第二个事件现在会想这样:
<event-handler event="message.create" access="public">
<event-bean name="message" type="MyGuestbook.model.message.message" />
<notify listener="messageListener" method="createMessage" />
<notify listener="messageListener" method="getAllMessages" resultKey="request.qry_messages" />
<view-page name="mainTemplate" />
</event-handler>
4.删除数据
我们不希望留言本失去控制.我们不希望保留那些垃圾信息,例如广告等.我们需要作一些修改或者直接删除信息在数据库里,但这样不怎么友好.我们在mach-ii.xml里了解不到多少这方面的信息.所以我们开始研究如何删除留言.