The other day, I was flipping through the ColdFusion docs (yeah, super exciting!) and came across the section about ColdFusion's support of ORM.  If you're not familiar with it (I wasn't really until a few days ago), ORM stands for "object-relational mapping." While it sounds a bit overly technical, ORM is basically a way to interface objects in code to relational databases that levels the playing field, allowing your code to be more or less agnostic about what kind (or kinds) of databases that it's connecting to.

At first, I was unimpressed, but then I took a few moments to think about it.  How often have I had to switch between database systems?  Plenty.  And how fun was it to have to go back and rework my code to account for the differences in typing and syntax?  It wasn't.  With ORM, however, alot of these headaches are removed because you can create an abstraction layer in your application using ORM to not really have to worry about what datasource you might be connecting to.

Now obviously, the subject of ORM is much more complex than my admittedly weak description.  However, after a lot of reading I feel like I have a decent idea on what the approach is, at least, so I decided to try my hand at a little ORM development.

As with most things, ColdFusion 9 makes ORM development stupidly simple.  Utilizing skills that you already have, you can make a few tweaks here and there and have some seriously cool ORM action up and running in a matter of minutes.

So let's look at some of the peices.

First, in Application.cfc, you have to turn ORM "on" and tell CF which datasource you want to use for this ORM voodoo.  This is accomplished pretty easily:

this.ormenabled = "true";
this.datasource = "my_test_orm_db";

Next, you'll want to start creating some CFC's–something tells me you've done this before πŸ™‚

But before we do that, the CFC is going to be a bit different than it might otherwise be.  Rather than creating a collection of functions and properties that are just kind of grouped together, this CFC is going to be created for the express purpose of describing a data object.  It's going to be the interface for how our ORM app colludes with the database.

component persistent="true" {
    property name="jobid" generator="increment" fieldtype="id" ormtype="integer";
    property name="title" ormtype="string";
    property name="description" ormtype="string";
    property name="startdate" ormtype="date";
    property name="enddate" ormtype="date";
    property name="datecreated" ormtype="timestamp";
    property name="lastupdated" ormtype="timestamp";
}

In this example (done completely in cfscript, btw–thank you CF9!!), I create a component like normal, but add the attribute "persistent" to it.  This attribute will tell ColdFusion to persist this object (which is really like a dataconnection to a particular table in your db) in the application so that you can interface with this object to perform your run-o-the-mill CRUD ops.

After creating the component, I simply add a property for each column in my table that will be the "maps" that ColdFusion uses to interact with the database.

Ok, so once this object gets persisted in the application, ColdFusion is going to do something terrifically cool.  For this object, it's going to create a bunch of standard methods that can be used for retreiving information about the object, updating it, creating new objects, and even deleting it.  Additionally, it's going to create getters and setters for each property for super-easy retrieval later on.

So let's see how this plays out.  Let's say that I want to create a new "Job" record in my "jobs" table in the db.  Before, I probably would have created a component for "jobs" and added a method to it called "createJob."  CreateJob() would have taken some arguments, and then performed a query to the db…pretty

standard stuff.  With ORM, however, this is more or less ALREADY READY TO GO now that I've finished defining my data object.  

Now, I can simply do the following (this is on a non-cfc page where I have a form action or something):

<cfset job = EntityNew("jobs")>
<cfset job.setTitle("Web Designer")>
<cfset job.setDescription("A full-time position for the best damn web designer out there")>
<cfset job.setStartDate("2010-03-10")>
<cfset job.setEndDate("2010-03-21")>
<cfset EntitySave(job)>

Here, I create a new instance of my "jobs" object with EntityNew().  Again, EntityNew() was auto generated by CF–I didn't have to worry about it.  Next, I simply set the value of each property of my object that I want to create using set<property>().  And again, the method is auto-created by CF.  Once I've set all the properties that I want for my new object, I can simply commit it and save my object using EntitySave(), yet another auto-generated method.

And…that's it.  If I check my database table, I'll see that a new record has been added with all the values that I applied to the object that was created and saved.

Now if you're like me, and are still kind of mired in older-school ways of thinking about data connections, this can be a trip.  After all, where the heck is the query?!?!  But that's the beauty of ORM.  After defining the properties of my data object, I don't have to worry necessarily about SQL syntax to get data into and out of my database.  Rather, I can use the definition I've created about my data to interface with the database and be happy and healthier for it.

So over the next several weeks, I'm going to be experimenting alot more with ORM, and hopefully will post some more thoughts.  But before I go, let me share my initial impressions.

One of the big reasons I like this approach is that it really forces you to start thinking in a more object-oriented manner. Of course, ORM is no magic bullet for developing an OO app, but I think the way in which it makes you think about your data is a very strong step in that direction.  Secondly, and related, I like that it turns data into objects.  In other modes of programming, it's very easy to get very lost in patching together code here and there to get something functional.  However, this approach really makes you think about the connections that your data have with one another, and I think helps to guide the way in which you approach developing an application in order to support these relationships.

Of course, I have very limited knowledge of OO, so I might be way off.  However, I feel like this is a move in the right direction, so let's see where it leads πŸ™‚