Object Oriented Coldfusion : 7.2 : Basic DAO Example

Posted on October 23, 2007

Ok, so we’ve got the concept of a DAO and how it interacts with a bean. Here’s an example of a form and an action page using Object Oriented Coldfusion.

A Form and an Action page

Let’s say you’ve got a page with a list of Contacts, each item has a link to contact_form.cfm with the CONTACT_ID in the query string.

contact_list.cfm

<cfset contactList = application.ContactGateway.getContacts() />

<ul>
<cfoutput query="contactList">
  <li>
    <a href="contact_form.cfm?CONTACT_ID=#contactList.CONTACT_ID#">
      #contactList.LAST_NAME#, #contactList.FIRST_NAME#
    </a>
  </li>
</cfoutput>
</ul>

### output

  • Filch, Argus
  • Granger, Hermione
  • McGonagall, Minerva</li>
  • Potter, Harry
  • Harry, Ron
  • </ul> ### Updating a record This form is going to update an existing record. ### contact_form.cfm?CONTACT_ID=3 ```cfscript <cfset categories = application.categoryGateway.getCategories() /> <cfset contact = createObject("component", "Contact").init( CONTACT_ID = url.CONTACT_ID ) /> <cfset application.contactDAO.read( contact ) />

    Category:

    Last Name:

    </form> </cfoutput> ``` ### output Category: First Name: Last Name:
    As for the processing page to update this Contact record, you have a few options: ### contact_update.cfm 1. Passing ordered argument values: ```cfscript <cfif structKeyExists(form, "processContact")> <cfset contact = createObject("component", "Contact").init( form.CONTACT_ID, form.CATEGORY_ID, form.FIRST_NAME, form.LAST_NAME ) /> <cfset application.contactDAO.update( contact ) /> </cfif> ``` 2a. Passing name / value pairs: ```cfscript <cfif structKeyExists(form, "processContact")> <cfset contact = createObject("component", "Contact").init( CONTACT_ID = form.CONTACT_ID, CATEGORY_ID = form.CATEGORY_ID, FIRST_NAME = form.FIRST_NAME, LAST_NAME = form.LAST_NAME ) /> <cfset application.contactDAO.update( contact ) /> </cfif> ``` 2b. Passing name / value pairs using `cfinvoke`: ```cfscript <cfif structKeyExists(form, "processContact")> </cfif> ``` 3a. Since the form field names match the argument names of the Update() method, you can pass the form scope as an `Argument Collection`: ```cfscript <cfif structKeyExists(form, "processContact")> <cfset contact = createObject("component", "Contact").init( argumentCollection = form ) /> <cfset application.contactDAO.update( contact ) /> </cfif> ``` 3b. Passing an `Argument Collection` using `cfinvoke`: ```cfscript <cfif structKeyExists(form, "processContact")> </cfinvoke> </cfif> ``` ### Creating a record If you wanted to create a new Contact, you could simply pass CONTACT_ID=0 in the query string to contact_form.cfm. This would create an empty bean and therefore an empty form. Now the question that should come to mind here is, "why should I read from the database when CONTACT_ID=0? The answer is, you shouldn't. With a simple update to the `read()` method, we can bypass running the query and re-populating the bean under this condition. ### ContactDAO.cfc - read() ```cfscript <cfif arguments.contact.getContactID() neq 0> SELECT CONTACT_ID, CATEGORY_ID, FIRST_NAME, LAST_NAME FROM CONTACTS WHERE CONTACT_ID = <cfif qReadOne.recordcount eq 0> <cfset arguments.contact.init( CONTACT_ID = qReadOne.CONTACT_ID, CATEGORY_ID = qReadOne.CATEGORY_ID, FIRST_NAME = qReadOne.FIRST_NAME, LAST_NAME = qReadOne.LAST_NAME ) /> </cfif> </cfif> </cffunction> ``` The only change you'd make to contact_form.cfm would be to set the action page to something like contact_create.cfm in order to run the create() method instead of the update() method from ContactDAO.cfc. ### contact_form.cfm - dynamic action ```cfscript <cfif url.CONTACT_ID neq 0> </cfif> <cfset categories = application.categoryGateway.getCategories() /> <cfset contact = createObject("component", "Contact").init( CONTACT_ID = url.CONTACT_ID ) /> <cfset application.contactDAO.read( contact ) />
    ``` Now we're using the same contact_form.cfm to both Update and Create a Contact. The only difference is the output: ### output Category: First Name: Last Name:
    Finally, here's the action page for creating a Contact: ### contact_create.cfm ```cfscript <cfif structKeyExists(form, "processContact")> <cfset contact = createObject("component", "Contact").init( CONTACT_ID = form.CONTACT_ID, CATEGORY_ID = form.CATEGORY_ID, FIRST_NAME = form.FIRST_NAME, LAST_NAME = form.LAST_NAME ) /> <cfset application.contactDAO.create( contact ) /> </cfif> ``` Does that look familiar? The only difference between contact_create.cfm and contact_update.cfm is that we're calling `create()` instead of `update()`. Even though the `create()` method doesn't require the CONTACT_ID, since we're passing data in name / value pairs, the order of the arguments doesn't matter. CONTACT_ID will be passed to the method, but it just won't be used for any part of the process that creates a record in the database. ## Where's Hagrid? When we first meet Rubeus Hagrid in "Harry Potter and The Sorcerer's Stone" (actually, in "The Philosopher's Stone") he is the Gamekeeper for Hogwarts School of Witchcraft and Wizardry. In the second book, "The Chamber of Secrets", Hagrid has kept his Staff position, but is now also an Instructor, teaching `Care of Magical Creatures`. As the database layout stands now, each Contact can have only one Category. In order to properly enter Professor Hagrid into the Hogwarts database, we'll have to make some changes to the database tables to allow a single Contact record to map to multiple Category records and vice versa. We'll also need a more Complex Data Access Object to handle this new many-to-many (*:*) relationship.

About the Author
Adrian J. Moreno

Adrian is a CTO and solution architect specializing in software modernization. More information