Transfer ORM Cheat Sheet
December 09, 2008
A little quick start guide I've put together for Transfer ORM
Initialising Transfer (as a Singleton)
<cfset application.transferFactory =
createObject("component", "transfer.TransferFactory").init(
"/config/datasource.xml.cfm",
"/config/transfer.xml.cfm",
"/config/definitions") />
<!--- shorthand reference to getTransfer --->
<cfset Application.transfer = application.transferFactory.getTransfer() />
datasource.xml.cfm
<?xml version="1.0" encoding="UTF-8"?> <datasource xsi:noNamespaceSchemaLocation="../transfer/resources/xsd/datasource.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <name>aliaspooryorik</name> <username></username> <password></password> </datasource>
transfer.xml.cfm
<?xml version="1.0" encoding="UTF-8"?>
<transfer
xsi:noNamespaceSchemaLocation="../transfer/resources/xsd/transfer.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<objectDefinitions>
<object name="Post" table="BlogPosts">
<!--
---------------------------------------------------------
attributes
---------------------------------------------------------
name
required
type
required
[numeric|string|date|boolean|UUID|GUID]
column
optional (default: name)
generate
optional
[true|false]
nullable
optional (default: false)
---------------------------------------------------------
-->
<id name="id" column="post_id" type="numeric" generate="true" />
<property name="status" type="boolean" column="post_status" nullable="false" />
<property name="title" type="string" column="post_title" nullable="false" />
<property name="views" type="string" column="post_views" nullable="false" />
</object>
</objectDefinitions>
</transfer>
A couple of gotchas to look out for before we even start any code!
- The object name is case sensitive!
- You will need to create the 'definitions' directory - Transfer will not do that for you!
Get an object by id
<cfset post = application.transfer.get("Post", 1) />
Debugging (only use getMemento for debugging)
<cfset post = application.transfer.get("Post", 1) />
<cfdump var="#post.getMemento()#" />
Displaying values
<cfset post = application.transfer.get("Post", 1) />
<cfoutput>
Name: #post.getTitle()#
</cfoutput>
Delete an object by id
<cfset post = application.transfer.get("Post", 1) />
<cfset application.transfer.delete(post) />
Create an empty object (preferred)
<cfset post = application.transfer.new("Post") />
Create an empty object (alternative)
<cfset post = application.transfer.get("Post", 0) />
Note that there must not be a post object with an id of 0.
Save a new object
<cfset post = application.transfer.new("Post") />
<cfset post.setTitle("Transfer is mighty impressive!") />
<cfset application.transfer.save(post) />
Update an existing object
<cfset post = application.transfer.get("Post", 1) />
<cfset post.setTitle("Transfer is not as complicated as you think!") />
<cfset application.transfer.save(post) />
Getting an query object ordering by 'title' property ascending (A-Z)
<cfset posts = application.transfer.list("Post", "title") />
<cfdump var="#posts#" />
Getting an query object ordering by 'title' property descending (Z-A)
<cfset posts = application.transfer.list("Post", "title", false) />
<cfdump var="#posts#" />
Getting an query object filtering by a property
<cfset activeposts = application.transfer.listByProperty("Post", "status", True) />
<cfdump var="#activeposts#" />
Getting an query object filtering by multiple properties
<cfset map = StructNew() />
<cfset map.views = 0 />
<cfset map.status = True />
<cfset activepostswithnoviews = application.transfer.listByPropertyMap("Post", map) />
<cfdump var="#activepostswithnoviews#" />
Decorators (are cool!)
Add the component path to the Transfer XML config file
<object name="User" table="users" decorator="model.transferdecorators.user">
An example decorator
<cfcomponent extends="transfer.com.TransferDecorator" displayname="User" output="false">
<cffunction name="getAgeInYears"
access="public"
returntype="numeric"
output="false"
hint="I am a new method">
<cfreturn DateDiff( 'y', getDateOfBirth(), Now() ) />
</cffunction>
<cffunction name="getImage"
access="public"
returntype="numeric"
output="false"
hint="I override the default getImage method">
<!--- need to use the getTransferObject() method to access the original method --->
<cfset var imagefilename = getTransferObject().getImage() />
<cfif imagefilename eq "">
<cfset imagefilename = "stub-profile-image.jpg" />
</cfif>
<cfreturn imagefilename />
</cffunction>
</cfcomponent>
Using onetomany Compositions
In this Transfer snippet, one Bookshelf can have many Books, so use a onetomany composition.
<object name="Bookshelf">
<id name="BookshelfID" type="numeric" />
<property name="Name" type="string" />
<onetomany name="Book" lazy="true" proxied="true">
<link column="fk_bookshelfid" to="Book" />
<collection type="array">
<order property="Name" order="asc" />
</collection>
</onetomany>
</object>
To get an array of Books you'd do this.
<cfset Bookshelf = application.transfer.get( "Bookshelf", 1 ) />
<cfset Book = Bookshelf.getBookArray() />
TQL (Transfer Query Language)
Transfer allows you to write your own queries. It is worth noting that unlike SQL statements, TQL statements are executed against your objects, not the database tables.
It is important to note that if you are adding the TQL inside a cffunction tag which has the attribute of output="false", then you will need to wrap the TQL in a cfoutput tag.
<cfsavecontent variable="tql">
SELECT Book.Name
, Bookshelf.Name
FROM library.Book as Book
JOIN library.Bookshelf as Bookshelf
WHERE Bookshelf.BookshelfID = :id
ORDER BY Bookshelf.Name
</cfsavecontent>
<cfset query = getTransfer().createQuery( tql ) />
<cfset query.setParam( "id", "1", "numeric" ) />
<cfset result = getTransfer().listByQuery( query ) />
Using the TQL Custom Tags
<cfimport prefix="t" taglib="/transfer/tags" />
<t:query name="result" transfer="#getTransfer()#">
SELECT Book.Name
, Bookshelf.Name
FROM library.Book as Book
JOIN library.Bookshelf as Bookshelf
WHERE Bookshelf.BookshelfID = <t:queryparam value="#id#" type="GUID">
ORDER BY Bookshelf.Name
</t:query>
If you use joins then Transfer knows how to construct the relationship by using the compositions you set up in Transfer.xml.
- Posted in:
- SQL
- ColdFusion
- Resources
- Transfer
4 comments
Leave a comment
If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)





Comment by Josh Grauer – January 21, 2009
Comment by Reinhard Jung – August 10, 2009
You might want to try posting to the mailing list:
groups.google.com/group/transfer-dev
Comment by John Whish – August 13, 2009
Just started using Transfer and this cheat sheet has proved valuable in getting head round it!
Comment by jbuda – March 12, 2010