ColdFusion-ORM: Define Computed properties (formula attribute)
What are computed properties?
Consider the tables – Art and Artists. Art and Artists form a one-to-many relationship where one Artist has created many Art. Say, in each Artist object, you need a property that would contain the number of arts made by the Artist – use computed properties. The formula to compute the value of the property should be specified using the formula attribute of the cfproperty tag. The formula should be specified as a SQL that returns a single value. Note that computed properties do not map to any column in the table and are not persistent.
Task:
Example to demonstrate using computed properties in ColdFusion-ORM
Previous Related Posts:
Getting Started with ORM
ColdFusion-ORM: Using CRUD Functions
ColdFusion-ORM: Define One-to-Many and Many-to-one relationships
ColdFusion-ORM: Collections
Stuff that you would learn:
- how to define computed properties
- how to define the formula for computed properties
Steps to Run the example:
- This example needs the cfartgallery datasource. This is shipped with ColdFusion by default.
- Create a directory say "ormformula" under webroot.
- Create the following files – Application.cfc, Artists.cfc and index.cfm.
- Run the URL “http://<ip>:<port>/ormformula/index.cfm”
Application.cfc
component
{
//Name of the application
this.name = "ORM_Formula";
//ormenabled should be set to true so that ORM is enabled for this application
this.ormenabled = "true";
//Set the datasource that needs to be used by the ORM Functions. You can also set this in the ormsettings struct
this.datasource = "cfartgallery";
}
Artists.cfc
component persistent="true" entityname="Artists" table="Artists"
{
property name="id" column="ARTISTID" generator="increment";
property name="firstname";
property name="lastname";
property name="address";
property name="city";
property name="state";
property name="postalcode";
property name="email";
property name="phone";
property name="fax";
property name="thepassword";
/*
A property automatically becomes a computed property if formula attribute is specified.
A SQL that returns a single value should be input to the formula attribute. Note
that computed properties do not map to any column in the table and are not persistent.
In this example, the "numberOfArts" property will store the number of arts made by the
Artist.
Have a close look at the SQL that is used. In this SQL, if you specify any column name, by default,
hibernate assumes that the column is from the table to which this CFC maps to - here
Artists table. If you want to specify a column that belongs to another table, you should alias
them. Hence, here, in the where condition art.ArtistId=ArtistId, the latter 'ArtistId' would be
from the Artists table. For each Artists entity, Hibernate would then substitue 'ArtistId' with
the column-value for that entity. For example, for the entity with ArtistId=5, the SQL would be:
select Count(*) from Art art where art.ArtistId=5
*/
property name="numberOfArts" formula="select Count(*) from Art art where art.ArtistId=ArtistId";
}
index.cfm
<!---
This example will teach you
- how to define computed properties
- how to define the formula for computed properties
--->
<cfset ormreload()>
<cfset artists = EntityLoad("Artists")>
<cfloop array="#artists#" index="artist">
<cfoutput>
#artist.getFirstName()# #artist.getLastName()# has <b>#artist.getNumberOfArts()#</b> arts<br>
</cfoutput>
</cfloop>
ColdFusion ORM: ORM-CFC Generator Extension for Adobe ColdFusion Builder
When we started working on ColdFusion-ORM feature (me and Rupesh), the only way to provide ORM mapping was by using the hibernate XML file (hbm.xml). Later, we provided a way to specify the mapping in CFCs – ColdFusion-ORM would then take care of creating the hibernate mapping. This made life easier for the ColdFusion developers. Now we have the ORM-CFC Generator Extension in Adobe ColdFusion Builder which will generate ORM-CFCs automatically!
The Adobe CFC Generator can be downloaded from this location and the instructions to use it are here. The Adobe CFC Generator
- allows you to create ORM-CFCs from a set of tables.
- allows you to configure the ORM-CFCs – change the CFC-Name, change EntityName, change property-name, select/de-select columns, add relationships and join-conditions, etc.
- generates ORM-CFCs (of-course!)
- generates Service CFCs for each ORM-CFC that contain certain utility methods to work with the ORM-entities
Note that the Adobe CFC Generator is provided as a sample extension. When the extension is installed, the source-code for the extension can be found in the installed location. Using the source code, you can modify/customize the UI/ORM-cfcs/Service-cfcs to add additional functionality.
Check out this blog post – How Do I generate ORM CFC’s??? – A nice captivate demo which shows you how to install and use ORM-CFC Generator Extension. The CFBuilder team will be posting heavily on extensions in the coming days – do have an eye on that space.
ColdFusion-ORM: Collections
In this post, I will digress a bit and introduce you to a lighter feature of ColdFusion-ORM – COLLECTIONS.
What are collections?
Consider the same tables we have been using – Art and Artists. Say, in the Artist object, you just need an array/struct of Art names instead of an array/struct of the Art objects, then use collections.
Task:
Example to demonstrate collections in ColdFusion-ORM
Previous Related Posts:
Getting Started with ORM
ColdFusion-ORM: Using CRUD Functions
ColdFusion-ORM: Define One-to-Many and Many-to-one relationships
Stuff that you would learn:
- how to create a collection as an array
- how to create a collection as a struct
- how to create a sorted collection
Steps to Run the example:
- This example needs the cfartgallery datasource. This is shipped with ColdFusion by default.
- Create a directory say "ormcollections" under webroot.
- Create the following files – Application.cfc, Artists.cfc and index.cfm.
- Run the URL http://localhost:8500/ormcollections/index.cfm
In this example, I have put comments only in Artsists.cfc. Please read the previous posts if need information about the other files.
Application.cfc
component
{
//Name for the application
this.name = "ORM_Collections";
//ormenabled should be set to true so that ORM is enabled for this application
this.ormenabled = "true";
/*
Set the datasource that needs to be used by the ORM Functions.
You can also set this in the ormsettings struct
*/
this.datasource = "cfartgallery";
}
Artists.cfc
component persistent="true"
{
property name="artistid" generator="increment";
property name="firstname";
property name="lastname";
property name="address";
property name="city";
property name="state";
property name="postalcode";
property name="email";
property name="phone";
property name="fax";
property name="thepassword";
/*
Artists have many arts. Using Collections, the name of the arts created by
each artist can be retrieved as a string array. Note that the art names
is picked from the table and you don’t require the ART component. This also means
that you get an array of strings and not an array of persistent objects.
For doing this, first of all, set fieldtype="collection".
type: can be "array" or "struct". Defaults to array. If type=array, the art
names are retrieved as an array of names. If type=struct, the art names are
retrieved as key-value pairs.
table: The name of the table in which the collection needs to be retrieved from.
fkcolumn: The name of the foriegn key. If not specified, will be figured
out by inspecting the database.
elementcolumn: The name of the table column which should be the retrieved as
the values of the array/struct. In this case, the names of the arts (Art->artname).
elementtype: The datatype of the table column used in elementcolumn.
orderby: Specify the sort order. The string should be specified in the format
"<column_name_1> <sort_order>, <column_name_2> <sort_order>, ...". <column_name>
should be the name of the column name of the table. <sort_order> is "desc" or "asc".
*/
property name="ArtNamesAsArray" fieldtype="collection" table="Art"
fkcolumn="artistid" type="array" elementtype="string" elementcolumn="artname"
orderby="artname desc";
/*
Here is one more property which retrieves artnames but it retrieves it as a struct.
Two additional attributes are requried to defined for this collection type - structkeycolumn and
structkeytype in addition to the attributes used for fieldtype="collection" for type="array".
Structkeycolumn: Specify the column name of the table which should be used for the keys of the struct.
This column should be unique for the records that are retrieved. Here, the column artid is used.
Structkeytype: The type of the column that is used in structkeycolumn.
*/
property name="ArtNamesAsStruct" fieldtype="collection" table="Art" fkcolumn="artistid"
type="struct" elementtype="string" elementcolumn="artname" structkeytype="int"
structkeycolumn="artid" orderby="artid";
}
index.cfm
<!---
This example will teach you Collections.
- how to create a collection as an array
- how to create a collection as a struct
- how to create a sorted collection
cfartgallery datasource is used for this application.
Artists table is one of the table in cfartgallery which contains a list of
artists records. Arts is one other table which contains a list of arts created
by artists. Artists has a one-to-many relationship with Arts records.
Artists and Arts tables are used in this example.
--->
<cfscript>
/*
Load the artists
*/
artists = EntityLoad("Artists");
WriteOutput("<b>Display the Artist name and the name of their arts which we got as an array<br /></b>");
for (i=1;i<=ArrayLen(artists);i++)
{
artist = artists[i];
/*Retrieve the Names of the Arts created by the artist
The Art-Names are retrieved as an array
*/
artNameArray = artist.getArtNamesAsArray();
/*
Display the Artist Name and their arts
*/
WriteOutput("<b>" & artist.getFirstName() & " " & artist.getLastName() & "</b> has created ");
if (ArrayLen(artNameArray))
{
for (j=1;j<=ArrayLen(artNameArray);j++)
{
WriteOutput('<i>' & artNameArray[j] & '</i>, ');
}
}
else
{
WriteOutput("<i>none</i>");
}
WriteOutput("<br>");
}
WriteOutput("<br>");
/*
In the above section, retrieving art names as a array is shown. The following section retrieves the
art names as a struct
*/
WriteOutput("<b>Display the Artist name and his arts which we got as struct<br /></b>");
for (i=1;i<=ArrayLen(artists);i++)
{
artist = artists[i];
/*
Retrieve the names of arts. The Art Names are retrieved as a struct
The keys of the struct are the IDs of the respective arts.
*/
artNameStruct = artist.getArtNamesAsStruct();
/*
Display the Artist Name and their arts.
*/
WriteOutput("<b>" & artist.getFirstName() & " " & artist.getLastName() & "</b> has created ");
artNameKeyArray = StructKeyArray(artNameStruct);
if (ArrayLen(artNameKeyArray))
{
for (j=1;j<=ArrayLen(artNameKeyArray);j++)
{
/*
Art ID is a integer. Hence using the java method to retrieve the value of the struct member
*/
WriteOutput('<i>' & artNameStruct.get(javacast("int", artNameKeyArray[j])) & '</i>, ');
}
}
else
{
WriteOutput("<i>none</i>");
}
WriteOutput("<br>");
}
</cfscript>



Recent Comments