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>
ColdFusion-ORM: Define One-to-Many and Many-to-one relationships
Task:
Example to demonstrate how to establish one-to-many and many-to-one Relationships in ColdFusion-ORM
Previous Related Posts:
Getting Started with ORM
ColdFusion-ORM: Using CRUD Functions
Stuff that you would learn:
- how to establish a One-to-Many relationship between 2 CFCs.
- how to establish a Many-to-One relationship between 2 CFCs.
- how to do CRUD operations with CFCs which have a relationship.
- how to use the implicit relationship methods added by ColdFusion.
- cascade insert and delete
Steps to Run the example:
- This example needs the cfartgallery datasource. This is shipped with ColdFusion by default.
- Create a directory say "1tonorm" under webroot.
- Create the following files – Application.cfc, Art.cfc, Artists.cfc and index.cfm.
- Run the URL http://localhost:8500/1tonorm/index.cfm
I have interspersed the example with a lot of comments. You can understand the concept by just following the comments starting with Application.cfc and then Artists.cfc and then Arts.cfc and then index.cfm.
Application.cfc
component
{
//Name of the application
this.name = "ORM_One2Many";
//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.
this.datasource = "cfartgallery";
}
Artists.cfc
component persistent="true"
{
property name="artistid" generator="increment";
property firstname;
property lastname;
property address;
property city;
property state;
property postalcode;
property email;
property phone;
property fax;
property thepassword;
/*
Artists have many arts and henace they form a one-to-many relation. The idea is to have all
the arts as an array of art objects in each Artists' object.
Set fieldytpe="one-to-many".
Specify CFC="Art" to convey that the relationship is with Art.cfc.
fkcolumn="artistid" to specify the foreign key. But this is not required if foreignkey constraint
is defined in the database - ColdFusion-ORM will figure it out by inspecting the database.
cascade="all-delete-orphan": "all" signifies that all the CRUD operations will be cascaded to the
related objects. "delete-orphan" means that it will delete the orphan objects in the art array
i.e. if i remove an art from the arts array, it is now an orphan as it has no artist associated
with it and hence will be automatically deleted.
Implit Methods: When a one-to-many relationship is established, the following implicit methods are introduced
into the artist object:
void addart(<artobj>) - used to add a art object to the relationship.
boolean removeart(<artobj>) - used to remove the art object from the relationship.
boolean hasart() - to check if there are any art objects in the artist object.
boolean hasart(<artobj>) - to check if the input art object is present in the artist object.
singularname: Use this attribute to specify custom name to the above implicit methods.
type=array: To retrieve the arts objects as an array. If type="struct", then the arts objects are retrieved as
key-value pairs. structkeycolumn and structkeytype should be specified in addition to all the above attributes
to retrieve arts as key-value pairs.
inverse=true: In a bi-directional relationship like this, you should specify one of the side as the controlling side
which will set the relationship. Usually, in a one-to-many bi-directional relationship, the many-to-one side should
be the controlling side. To do that, set inverse=true on this side (one-to-many side).
*/
property name="arts" type="array" fieldtype="one-to-many" cfc="Art" singularname="art" fkcolumn="artistid"
inverse="true" cascade="all-delete-orphan";
}
Art.cfc
component persistent="true"
{
property name="artid" generator="increment";
property name="artname";
property name="price";
property name="largeimage";
property name="mediaid";
property name="issold";
/*
Many arts have an artist and hence form a "many-to-one" relation.
To establish a "many-to-one" relation, set fieldytpe="many-to-one"
Specify CFC="Artists" to convey that the relationship is with Artists.cfc.
fkcolumn="artistid": Used to specify the foreign key.
missingRowIgnored: If the value is true, and the row that is referenced by the foreign
key is missing, it is treated as a null association.
*/
property name="artist" fieldtype="many-to-one" fkcolumn="artistid"
cfc="Artists" missingRowIgnored="true";
}
index.cfm
<!---
This example will teach you
- how to establish a One-to-Many relationship between 2 CFCs.
- how to establish a Many-to-One relationship between 2 CFCs.
- how to do CRUD operations with CFCs which have a relationship.
- how to use the implicit relationship methods added by ColdFusion.
- Using cascade in one-to-many to many-to-one relationships.
cfartgallery datasource is used for this application.
--->
<cfscript>
ormreload();
/*
Display the existing records in Artists Table.
This will display the artist and their arts.
*/
WriteOutput("<b>Initial state of the Artists and Art tables<br></b>");
DisplayArtists();
/*
Create an artist object and 2 art objects
*/
newArtist = new Artists();
newArtist.setfirstname("Daniel");
newArtist.setlastname("Richard");
newArt1 = new Art();
newArt1.setArtName("Champions");
newArt2 = new Art();
newArt2.setArtName("Isolate");
/*
Associate the Arts to the Artist. Notice that the
implicit-relationship method - addArt is called.
*/
newArtist.addArt(newArt1);
newartist.addArt(newArt2);
/*
The one-to-many relationship should be established from both
the ends. Hence set the Artist to the new Arts.
*/
newArt1.setArtist(newArtist);
newArt2.setArtist(newArtist);
/*
Save the new artist. Note that EntitySave will save the artist as
well as the associated arts as well (cascade-insert)
*/
EntitySave(newArtist);
ormflush();
/*
Display the existing records to check whether insert succeeded.
*/
WriteOutput("<b>State of the Artists and Art tables after insert. Notice that the new
artist - Daniel Richard is added with his arts 'Champions' and 'Isolate'<br></b>");
DisplayArtists();
/*
Remove newArt2 and add newArt3. In a way, you are just modifying the 'arts' array. Notice that
we are using the implicit=relationship method - removeArt is called.
*/
newArt3 = new Art();
newArt3.setArtName("Holiday");
newArt3.setArtist(newArtist);
newArtist.addArt(newArt3);
newArtist.removeArt(newArt2);
ormflush();
/*
Check if delete and update of art succeeded.
*/
WriteOutput("<b>State of the Artists and Art tables after Deleting/Updating his Arts. Notice that
the art 'Isolate' is removed and the art 'Holiday' is added.<br></b>");
DisplayArtists();
/*
Delete the Artist. Note that EntityDelete will delete
the Artist as well as the associated arts. (cascade-delete).
*/
EntityDelete(newArtist);
ormflush();
/*
Check if delete succeeded.
*/
WriteOutput("<b>State of the Artists and Art tables after deleting the Artist.
Notice that the artist 'Daniel Richard' is deleted. All his arts are also deleted!<br></b>");
DisplayArtists();
/*
A Utility function to display artists and his arts
*/
function DisplayArtists()
{
query1 = new Query();
query1.setSQL("select ArtistID, firstname, lastname from Artists where ArtistID>10");
WriteDump(query1.execute().getresult());
query1.setSQL("select ArtID, ArtName, ArtistID from Art where ArtID>50");
WriteDump(query1.execute().getresult());
}
</cfscript>



Recent Comments