SlideShare a Scribd company logo
Let ColdFusion ORM doLet ColdFusion ORM do
the work for you!the work for you!
CFSummit 2018CFSummit 2018
Presenter: Masha EdelenPresenter: Masha Edelen
Who am I?Who am I?
Full Stack Web Developer of 16+ years
HD Web Studio Owner and Visionary
Mother to a Teenage Daughter
Travel Enthusiast
Live Music Fan
Amateur Latin Dancer
www.ColdFusionORMbook.com
AgendaAgenda
Introduction to ORM
Getting Started
Relationships
HQL
Gotchas
Advanced Features
Resources
What is ORM?What is ORM?
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSD628ADC4-A5F7-4079-99E0-FD725BE9B4BD.html
Object relational mapping (ORM) is a programming
framework that allows you to define a mapping between
application object model and the relational database.
ORM Implementaion in ColdFusionORM Implementaion in ColdFusion
Hibernate 5.3 - current stable
ColdFusion 2018 - Hibernate 5.2
ColdFusion 2016 - Hibernate 4.3
ColdFusion 11 - Hibernate 4.1
ColdFusion 10 - Hibernate 3.5
ColdFusion 9 - Hibernate 3.5
Lucee - Hibernate 3.5
Why should I use an ORM?Why should I use an ORM?
Reduces development time
Overcomes vendor specific SQL differences
Promotes effective design patterns
Reduces maintenance
Potential DownsidePotential Downside
Without proper tuning performance can suffer.
Make sure you optimize queries
and use effective caching strategy!
Getting StartedGetting Started
Step 1: Configuring ORM in your Application
Application.cfc
component {
// set the unique name of the application
this.name = "myCMS";
// set the datasource
this.datasource = "mydsn";
// turn ORM on
this.ormenabled = true;
}
Step 2: Mapping Tables to Objects
Article.cfc
/*** I model a blog article ***/
component persistent="true" table="articles" {
// identifier
property name="id" fieldtype="id" generator="native" column="articleI
// properties
property name="title" ormType="string" length="250";
property name="summary" ormType="string" length="500";
property name="description" ormType="text";
}
AccessorsAccessors
setTitle()
getTitle()
Additional ORM SettingsAdditional ORM Settings
Application.cfc
// ORM settings
this.ormsettings = {
cfclocation = ["model/beans"],
dbcreate = "update",
dialect = "MySQL",
datasource = "ORMds",
useDBForMapping = false
}
ORMReload()ORMReload()
// ORM reload on URL
if (structKeyExists(url,"reloadORM")) {
ORMReload();
}
CRUDCRUD
Source: http://docs.jboss.org/hibernate/orm/4.1/quickstart/en-US/html/pr01.html
Hibernate’s design goal is to relieve the developer from 95%
of common data persistence-related programming tasks by
eliminating the need for manual, hand-crafted data
processing using SQL and JDBC.
CreateCreate
// Create music category
myCategory = EntityNew("Category");
myCategory.setTitle("Music");
EntitySave(myCategory);
// Create sports category
myCategory = EntityNew("Category", {title:"Sports"});
EntitySave(myCategory);
// Create family category
myCategory = new model.Category(title="Family");
EntitySave(myCategory);
// Create holiday category
myCategory = EntityNew("Category");
myCategory.title = "Holiday";
EntitySave(myCategory);
ReadRead
UpdateUpdate
DeleteDelete
// Get all categories
categories = EntityLoad("Category");
WriteDump(var = categories, top = 2);
// Get category and update its title
myCategory = EntityLoadByPK("Category", 1);
myCategory.setTitle("New Title");
// Delete category
myCategory = EntityLoadByPK("Category", 1);
EntityDelete(myCategory);
More ExamplesMore Examples
// Get all categories set to display
categories = EntityLoad("Category", {dsp = true});
// Get all categories set to display and ordered chronologically
categories = EntityLoad("Category", {dsp = true}, "date desc");
More ExamplesMore Examples
// Get category by ID
myCategory = EntityLoadbyPK("Category",1);
// Get category by ID
myCategory = EntityLoad("Category",1);
myCategory = EntityLoad("Category",1,true);
Convert Object to QueryConvert Object to Query
// Convert object to query
myCategory = EntityLoadbyPK("Category",1);
myCategoryQuery = EntityToQuery(myCategory);
// Convert array of objects to query
categories = EntityLoad("Category");
categoriesQuery = EntityToQuery(categories);
RelationshipsRelationships
One-to-ManyOne-to-Many
Author.cfc
/*** I model an Author ***/
component persistent="true" table="authors" {
// identifier
property name="id" fieldtype="id" generator="native";
// properties
property name="firstName" ormtype="string" length="50";
property name="lastName" ormtype="string" length="50";
// one Author can have many Articles
property name="articles" fieldtype="one-to-many" cfc="Article"
fkcolumn="fk_authorid" type="array" singularname="article";
}
One-to-Many MethodsOne-to-Many Methods
addArticle()
hasArticle()
removeArticle()
setArticles()
getArticles()
One-to-Many UsageOne-to-Many Usage
// Create a new article and add to an existing author
transaction {
// load the author
author = EntityLoadByPK("author", 1);
// create an article
article = EntityNew("article");
article.setTitle("ORM Makes My Life Easy!");
// attach the article to the author
author.addArticle(article);
// save the article
EntitySave(article);
};
writeDump(author.getArticles(), top="2");
Many-to-OneMany-to-One
Article.cfc
/*** I model an article ***/
component persistent="true" table="articles" {
// identifier
property name="id" fieldtype="id" generator="native";
...
//many Article entities can have one Author entity
property name="Author" fieldtype="many-to-one"
cfc="Author" fkcolumn="fk_authorid";
}
Many-to-One MethodsMany-to-One Methods
hasAuthor()
setAuthor()
getAuthor()
Many-to-ManyMany-to-Many
Category.cfc
/*** I model a category ***/
component persistent="true" table="categories" {
//identifier
property name="id" fieldtype="id" generator="native";
...
//category can be assigned to more than one article
property name="articles" fieldtype="many-to-many"
cfc="Articles" type="array" singularname="article"
linktable="articles_categories";
}
Many-to-Many MethodsMany-to-Many Methods
addArticle()
getArticles()
hasArticle()
removeArticle()
setArticles()
OO Modeling is Key!OO Modeling is Key!
ORM Persistence Model is a set of ORM Entities
related based on business logic of the application.
Objects vs Tables
Persistence Model vs Database Schemas
Data + Behavior vs Data
The Inverse AttributeThe Inverse Attribute
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// one author can have many articles
property name="articles" fieldtype="one-to-many"
cfc="Article" fkcolumn="fk_authorid" type="array"
singularname="article"
// added attributes
inverse="true" cascade="delete";
}
Cascading StrategiesCascading Strategies
none
delete
save-update
all
delete-orphan
all-delete-orphan
Sort OrderSort Order
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// one author can have many articles
property name="articles" fieldtype="one-to-many"
cfc="Article" fkcolumn="fk_authorid" type="array"
singularname="article"
inverse="true" cascade="delete"
// added sorting
orderby="datepublished desc";
}
Where FilterWhere Filter
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// getting only published articles
property name="publishedArticles" fieldtype="one-to-many"
cfc="Article" fkcolumn="fk_authorid"
orderby="datepublished desc"
// filter
where="ispublished = 1";
}
FormulasFormulas
Author.cfc
/*** I model an author ***/
component persistent="true" table="authors" {
...
// get count of active articles
property name="publishedArticleCount" setter="false"
formula="select count(*)
from Articles a
where author_pk = a.fk_authorid
and a.ispublished = 1";
}
HQLHQL
HQLHQL
Same as:
// get users
EntityLoad("User");
// get users with HQL
ORMExecuteQuery("from User");
SQL Injection PreventionSQL Injection Prevention
Same as:
Better:
Or:
// get user by ID
userid = 123;
EntityLoadByPK("User", id);
// get user by ID with HQL
ORMExecuteQuery("from User where id = #userid#", true);
// get user by ID with HQL using positional parameters
ORMExecuteQuery("from User where id = ?", [userid], true);
// get user by ID with HQL using named parameters
ORMExecuteQuery("from User where id = :id", {id=userid}, true);
HQL ExamplesHQL Examples
ORMExecuteQuery(hql, params [,unique] [,queryOptions])
// get users with usernames that start with letter J
q = ORMExecuteQuery(
"from user where username like :prefix", {prefix = "J%"}
);
// get art pieces priced over $400
q = ORMExecuteQuery(
"from art where price > :lowprice", {lowprice = 400}
);
// adding queryOptions
q = ORMExecuteQuery(
"from artist", false, {offset=5, maxresults=10, timeout=5}
);
Relationships HQLRelationships HQL
Get articles by Author ID:
The HQL way:
// load author
author = EntityLoadByPK("Author", 2);
// get this author's articles
articles = author.getArticles();
from article
where author.id = :authorID
Relationships HQLRelationships HQL
Get published articles by Author ID:
Get unique authors:
from article
where
author.id = :authorID
and
ispublished = :isPublished
select distinct a.author
from article a
where
a.ispublished = :isPublished
Hash MapsHash Maps
select new map(id as ID, title as TITLE)
from Article
order by title
From Love to Hate?From Love to Hate?
ErrorsErrors
Error during DDL export
Cannot simultaneously fetch multiple bags
Failed to lazily initialize a collection of role, no session or
session was closed
Illegal attempt to dereference collection
Incomplete Information?Incomplete Information?
LoggingLogging
{cfinstall}cfusionlog4j.properties
log4j.logger.org.hibernate.type=DEBUG
// turn on logging in development
this.ormsettings = {
...
logSQL = true
}
Hibernate Session ManagementHibernate Session Management
ORM session starts when the first CRUD method is called
and is closed when the request ends.
// manage session manually
this.ormsettings = {
...
//switch to false and use transactions
autoManageSession = false,
flushAtRequestEnd = false
}
Performance ImprovementsPerformance Improvements
Paging
Lazy Loading
Fetching Options
Batching
Caching
PagingPaging
// get 10 artists starting with #6
artists = ORMExecuteQuery(
"from artist", false, {offset=5, maxresults=10, timeout=5}
)
Lazy LoadingLazy Loading
lazy = "true" (default)
lazy = "extra"
lazy = "false"
Fetching OptionsFetching Options
fetch = "select" (default)
fetch = "join"
Batch FetchingBatch Fetching
At CFC level
At collections
// implement batching
component table="artist" batchsize="10"...
...
// get artist as usual
getArtist();
// implement batching for related entity
property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID" bat
...
// get all the art of a specific artist
artist.getArt();
CachingCaching
Session Level - built into ORM
Second Level - through external caching engine
Secondary Level CacheSecondary Level Cache
EHCache, JBossCache, OSCache, SwarmCache, Tangosol Coherence Cache
Application.cfc
// activate secondary level cache
this.ormSettings.secondaryCacheEnabled = true;
Secondary Level CacheSecondary Level Cache
At CFC level
At collections
// implement secondary level caching
component persistent="true" table="Artist" cacheuse="transactional" ...
// implement secondary level caching for related entities
property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID"
cacheuse="transactional";
Secondary Level CacheSecondary Level Cache
read-only
nonstrict-read-write
read-write
transactional
Caching HQLCaching HQL
// implement caching for HQL query
e = ORMExecuteQuery(
"from article where id = :id",
{id=1},
{cacheable=true, cachename='articles'}
);
Managing the CacheManaging the Cache
// clear cache for author
ORMEvictEntity( "author" );
ORMEvictEntity( "author", 1 );
// clear cache for articles
ORMEvictCollection( "author", "articles" );
ORMEvictCollection( "author", "articles", 1 );
// clear cache for HQL
ORMEvictQueries( "mycachename" );
ORMEvictQueries();
Advanced Use CasesAdvanced Use Cases
Query: Retrieve distinct countries of all addresses in alphabetical order.
SQL:
HQL:
Criteria API:
select distinct country from address ordered by country
select distinct country from address ordered by country
criteria.setProjection(projections.distinct(projections.property("Country")))
criteria.addOrder(order.asc("locality"));
ColdBox ORM ModuleColdBox ORM Module
https://www.forgebox.io/view/cborm
"This module provides you with several enhancements
when interacting with the ColdFusion ORM via Hibernate.
It provides you with virtual service layers, active record
patterns, criteria and detached criteria queries, entity
compositions, populations and so much more to make your
ORM life easier!
In other words, it makes using ORM not SUCK!"
There is more!There is more!
Convenience Methods
Versioning
Validation
ORM Search
Advanced Mapping
Event Handlers (Interceptors)
Online ResourcesOnline Resources
Developing Applications Adobe ColdFusion ORM
ColdFusion ORM Developer Guide
CF-ORM Google Group
Hibernate Documentation
ORM Slack Channel on CFML Slack Team
https://helpx.adobe.com/coldfusion/developing-applications/user-guide.html?topic=/coldfusion/developing-applications/morehelp/coldfusion-orm.ug.js
http://adobe.ly/LnJilm
http://groups.google.ca/group/cf-orm-dev
http://www.hibernate.org/docs
PublicationsPublications
Java Persistence with Hibernate
Adobe ColdFusion 9 Web Application Construction Kit, Volume 2:
Application Development
ColdFusion ORM
http://www.manning.com/bauer2/
http://forta.com/books/0321679199/
http://www.coldfusionormbook.com
Please submit your surveyPlease submit your survey
for a chance to win!for a chance to win!
Go to the ColdFusion Summit mobile app
Find this session: D103: Let ColdFusion ORM do the work for you!
Make sure you have registered for this session
Select the “Survey” link at the bottom of the session and complete the
survey
Each survey has a chance to win $25 Amazon Gift Certificate
Thank You!Thank You!
Masha Edelen
masha@hdwebstudio.com
@mashaedelen

More Related Content

What's hot

Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4
DEVCON
 
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
 Connecting Content Silos: One CMS, Many Sites With The WordPress REST API Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Caldera Labs
 
Drupal 8 Services
Drupal 8 ServicesDrupal 8 Services
Drupal 8 Services
Philip Norton
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
Nathan Eror
 
Revolution or Evolution in Page Object
Revolution or Evolution in Page ObjectRevolution or Evolution in Page Object
Revolution or Evolution in Page Object
Artem Sokovets
 
You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)
andrewnacin
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with Solr
Erik Hatcher
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4
DEVCON
 
DevOps and Chef
DevOps and ChefDevOps and Chef
DevOps and Chef
PiXeL16
 
Flask patterns
Flask patternsFlask patterns
Flask patternsit-people
 
SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!
Taras Oleksyn
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationJace Ju
 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency Injection
Philip Norton
 
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Getting Into Drupal 8 Configuration
Getting Into Drupal 8 ConfigurationGetting Into Drupal 8 Configuration
Getting Into Drupal 8 Configuration
Philip Norton
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010
ikailan
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
zfconfua
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
Adam Tomat
 

What's hot (20)

Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4
 
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
 Connecting Content Silos: One CMS, Many Sites With The WordPress REST API Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
 
Drupal 8 Services
Drupal 8 ServicesDrupal 8 Services
Drupal 8 Services
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
 
Revolution or Evolution in Page Object
Revolution or Evolution in Page ObjectRevolution or Evolution in Page Object
Revolution or Evolution in Page Object
 
You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with Solr
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4
 
DevOps and Chef
DevOps and ChefDevOps and Chef
DevOps and Chef
 
Flask patterns
Flask patternsFlask patterns
Flask patterns
 
SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!
 
Head First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & ApplicationHead First Zend Framework - Part 1 Project & Application
Head First Zend Framework - Part 1 Project & Application
 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency Injection
 
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
#11.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원학원,재직자/실업자교육학원,스프링교육,마이바...
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
Getting Into Drupal 8 Configuration
Getting Into Drupal 8 ConfigurationGetting Into Drupal 8 Configuration
Getting Into Drupal 8 Configuration
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
 

Similar to Let ColdFusion ORM do the work for you!

Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for JoomlaLuke Summerfield
 
Human Talks - StencilJS
Human Talks - StencilJSHuman Talks - StencilJS
Human Talks - StencilJS
Alexandre Koelsch
 
Gears User Guide
Gears User GuideGears User Guide
Gears User Guide
Muthuselvam RS
 
PHP MVC
PHP MVCPHP MVC
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
Alexander Varwijk
 
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to PluginDrupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
Acquia
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4
Heather Rock
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
PiXeL16
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
Mood analyzer-ng poland
Mood analyzer-ng polandMood analyzer-ng poland
Mood analyzer-ng poland
Sherry List
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
Python Ireland
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
erwanl
 
Ingesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptIngesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScript
Lucidworks
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesNCCOMMS
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
MongoDB
 
Tornadoweb
TornadowebTornadoweb
Tornadoweb
Osman Yuksel
 
Questioning the status quo
Questioning the status quoQuestioning the status quo
Questioning the status quo
Ivano Pagano
 

Similar to Let ColdFusion ORM do the work for you! (20)

Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for Joomla
 
Human Talks - StencilJS
Human Talks - StencilJSHuman Talks - StencilJS
Human Talks - StencilJS
 
Gears User Guide
Gears User GuideGears User Guide
Gears User Guide
 
PHP MVC
PHP MVCPHP MVC
PHP MVC
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to PluginDrupal 8, Where Did the Code Go? From Info Hook to Plugin
Drupal 8, Where Did the Code Go? From Info Hook to Plugin
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
Mood analyzer-ng poland
Mood analyzer-ng polandMood analyzer-ng poland
Mood analyzer-ng poland
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
Ingesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScriptIngesting and Manipulating Data with JavaScript
Ingesting and Manipulating Data with JavaScript
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_libraries
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Tornadoweb
TornadowebTornadoweb
Tornadoweb
 
Questioning the status quo
Questioning the status quoQuestioning the status quo
Questioning the status quo
 

Recently uploaded

みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 

Recently uploaded (20)

みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 

Let ColdFusion ORM do the work for you!

  • 1. Let ColdFusion ORM doLet ColdFusion ORM do the work for you!the work for you! CFSummit 2018CFSummit 2018 Presenter: Masha EdelenPresenter: Masha Edelen
  • 2. Who am I?Who am I? Full Stack Web Developer of 16+ years HD Web Studio Owner and Visionary Mother to a Teenage Daughter Travel Enthusiast Live Music Fan Amateur Latin Dancer
  • 4. AgendaAgenda Introduction to ORM Getting Started Relationships HQL Gotchas Advanced Features Resources
  • 5. What is ORM?What is ORM? http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSD628ADC4-A5F7-4079-99E0-FD725BE9B4BD.html Object relational mapping (ORM) is a programming framework that allows you to define a mapping between application object model and the relational database.
  • 6. ORM Implementaion in ColdFusionORM Implementaion in ColdFusion Hibernate 5.3 - current stable ColdFusion 2018 - Hibernate 5.2 ColdFusion 2016 - Hibernate 4.3 ColdFusion 11 - Hibernate 4.1 ColdFusion 10 - Hibernate 3.5 ColdFusion 9 - Hibernate 3.5 Lucee - Hibernate 3.5
  • 7. Why should I use an ORM?Why should I use an ORM? Reduces development time Overcomes vendor specific SQL differences Promotes effective design patterns Reduces maintenance
  • 8. Potential DownsidePotential Downside Without proper tuning performance can suffer. Make sure you optimize queries and use effective caching strategy!
  • 9. Getting StartedGetting Started Step 1: Configuring ORM in your Application Application.cfc component { // set the unique name of the application this.name = "myCMS"; // set the datasource this.datasource = "mydsn"; // turn ORM on this.ormenabled = true; }
  • 10. Step 2: Mapping Tables to Objects Article.cfc /*** I model a blog article ***/ component persistent="true" table="articles" { // identifier property name="id" fieldtype="id" generator="native" column="articleI // properties property name="title" ormType="string" length="250"; property name="summary" ormType="string" length="500"; property name="description" ormType="text"; }
  • 12. Additional ORM SettingsAdditional ORM Settings Application.cfc // ORM settings this.ormsettings = { cfclocation = ["model/beans"], dbcreate = "update", dialect = "MySQL", datasource = "ORMds", useDBForMapping = false }
  • 13. ORMReload()ORMReload() // ORM reload on URL if (structKeyExists(url,"reloadORM")) { ORMReload(); }
  • 14. CRUDCRUD Source: http://docs.jboss.org/hibernate/orm/4.1/quickstart/en-US/html/pr01.html Hibernate’s design goal is to relieve the developer from 95% of common data persistence-related programming tasks by eliminating the need for manual, hand-crafted data processing using SQL and JDBC.
  • 15. CreateCreate // Create music category myCategory = EntityNew("Category"); myCategory.setTitle("Music"); EntitySave(myCategory); // Create sports category myCategory = EntityNew("Category", {title:"Sports"}); EntitySave(myCategory); // Create family category myCategory = new model.Category(title="Family"); EntitySave(myCategory); // Create holiday category myCategory = EntityNew("Category"); myCategory.title = "Holiday"; EntitySave(myCategory);
  • 16. ReadRead UpdateUpdate DeleteDelete // Get all categories categories = EntityLoad("Category"); WriteDump(var = categories, top = 2); // Get category and update its title myCategory = EntityLoadByPK("Category", 1); myCategory.setTitle("New Title"); // Delete category myCategory = EntityLoadByPK("Category", 1); EntityDelete(myCategory);
  • 17. More ExamplesMore Examples // Get all categories set to display categories = EntityLoad("Category", {dsp = true}); // Get all categories set to display and ordered chronologically categories = EntityLoad("Category", {dsp = true}, "date desc");
  • 18. More ExamplesMore Examples // Get category by ID myCategory = EntityLoadbyPK("Category",1); // Get category by ID myCategory = EntityLoad("Category",1); myCategory = EntityLoad("Category",1,true);
  • 19. Convert Object to QueryConvert Object to Query // Convert object to query myCategory = EntityLoadbyPK("Category",1); myCategoryQuery = EntityToQuery(myCategory); // Convert array of objects to query categories = EntityLoad("Category"); categoriesQuery = EntityToQuery(categories);
  • 20.
  • 22. One-to-ManyOne-to-Many Author.cfc /*** I model an Author ***/ component persistent="true" table="authors" { // identifier property name="id" fieldtype="id" generator="native"; // properties property name="firstName" ormtype="string" length="50"; property name="lastName" ormtype="string" length="50"; // one Author can have many Articles property name="articles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" type="array" singularname="article"; }
  • 24. One-to-Many UsageOne-to-Many Usage // Create a new article and add to an existing author transaction { // load the author author = EntityLoadByPK("author", 1); // create an article article = EntityNew("article"); article.setTitle("ORM Makes My Life Easy!"); // attach the article to the author author.addArticle(article); // save the article EntitySave(article); }; writeDump(author.getArticles(), top="2");
  • 25. Many-to-OneMany-to-One Article.cfc /*** I model an article ***/ component persistent="true" table="articles" { // identifier property name="id" fieldtype="id" generator="native"; ... //many Article entities can have one Author entity property name="Author" fieldtype="many-to-one" cfc="Author" fkcolumn="fk_authorid"; }
  • 27. Many-to-ManyMany-to-Many Category.cfc /*** I model a category ***/ component persistent="true" table="categories" { //identifier property name="id" fieldtype="id" generator="native"; ... //category can be assigned to more than one article property name="articles" fieldtype="many-to-many" cfc="Articles" type="array" singularname="article" linktable="articles_categories"; }
  • 29. OO Modeling is Key!OO Modeling is Key! ORM Persistence Model is a set of ORM Entities related based on business logic of the application. Objects vs Tables Persistence Model vs Database Schemas Data + Behavior vs Data
  • 30. The Inverse AttributeThe Inverse Attribute Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // one author can have many articles property name="articles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" type="array" singularname="article" // added attributes inverse="true" cascade="delete"; }
  • 32. Sort OrderSort Order Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // one author can have many articles property name="articles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" type="array" singularname="article" inverse="true" cascade="delete" // added sorting orderby="datepublished desc"; }
  • 33. Where FilterWhere Filter Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // getting only published articles property name="publishedArticles" fieldtype="one-to-many" cfc="Article" fkcolumn="fk_authorid" orderby="datepublished desc" // filter where="ispublished = 1"; }
  • 34. FormulasFormulas Author.cfc /*** I model an author ***/ component persistent="true" table="authors" { ... // get count of active articles property name="publishedArticleCount" setter="false" formula="select count(*) from Articles a where author_pk = a.fk_authorid and a.ispublished = 1"; }
  • 36. HQLHQL Same as: // get users EntityLoad("User"); // get users with HQL ORMExecuteQuery("from User");
  • 37. SQL Injection PreventionSQL Injection Prevention Same as: Better: Or: // get user by ID userid = 123; EntityLoadByPK("User", id); // get user by ID with HQL ORMExecuteQuery("from User where id = #userid#", true); // get user by ID with HQL using positional parameters ORMExecuteQuery("from User where id = ?", [userid], true); // get user by ID with HQL using named parameters ORMExecuteQuery("from User where id = :id", {id=userid}, true);
  • 38. HQL ExamplesHQL Examples ORMExecuteQuery(hql, params [,unique] [,queryOptions]) // get users with usernames that start with letter J q = ORMExecuteQuery( "from user where username like :prefix", {prefix = "J%"} ); // get art pieces priced over $400 q = ORMExecuteQuery( "from art where price > :lowprice", {lowprice = 400} ); // adding queryOptions q = ORMExecuteQuery( "from artist", false, {offset=5, maxresults=10, timeout=5} );
  • 39. Relationships HQLRelationships HQL Get articles by Author ID: The HQL way: // load author author = EntityLoadByPK("Author", 2); // get this author's articles articles = author.getArticles(); from article where author.id = :authorID
  • 40. Relationships HQLRelationships HQL Get published articles by Author ID: Get unique authors: from article where author.id = :authorID and ispublished = :isPublished select distinct a.author from article a where a.ispublished = :isPublished
  • 41. Hash MapsHash Maps select new map(id as ID, title as TITLE) from Article order by title
  • 42. From Love to Hate?From Love to Hate?
  • 43. ErrorsErrors Error during DDL export Cannot simultaneously fetch multiple bags Failed to lazily initialize a collection of role, no session or session was closed Illegal attempt to dereference collection
  • 45. LoggingLogging {cfinstall}cfusionlog4j.properties log4j.logger.org.hibernate.type=DEBUG // turn on logging in development this.ormsettings = { ... logSQL = true }
  • 46. Hibernate Session ManagementHibernate Session Management ORM session starts when the first CRUD method is called and is closed when the request ends. // manage session manually this.ormsettings = { ... //switch to false and use transactions autoManageSession = false, flushAtRequestEnd = false }
  • 47. Performance ImprovementsPerformance Improvements Paging Lazy Loading Fetching Options Batching Caching
  • 48. PagingPaging // get 10 artists starting with #6 artists = ORMExecuteQuery( "from artist", false, {offset=5, maxresults=10, timeout=5} )
  • 49. Lazy LoadingLazy Loading lazy = "true" (default) lazy = "extra" lazy = "false"
  • 50. Fetching OptionsFetching Options fetch = "select" (default) fetch = "join"
  • 51. Batch FetchingBatch Fetching At CFC level At collections // implement batching component table="artist" batchsize="10"... ... // get artist as usual getArtist(); // implement batching for related entity property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID" bat ... // get all the art of a specific artist artist.getArt();
  • 52. CachingCaching Session Level - built into ORM Second Level - through external caching engine
  • 53. Secondary Level CacheSecondary Level Cache EHCache, JBossCache, OSCache, SwarmCache, Tangosol Coherence Cache Application.cfc // activate secondary level cache this.ormSettings.secondaryCacheEnabled = true;
  • 54. Secondary Level CacheSecondary Level Cache At CFC level At collections // implement secondary level caching component persistent="true" table="Artist" cacheuse="transactional" ... // implement secondary level caching for related entities property name="art" fieldtype="one-to-many" cfc="art" fkcolumn="artistID" cacheuse="transactional";
  • 55. Secondary Level CacheSecondary Level Cache read-only nonstrict-read-write read-write transactional
  • 56. Caching HQLCaching HQL // implement caching for HQL query e = ORMExecuteQuery( "from article where id = :id", {id=1}, {cacheable=true, cachename='articles'} );
  • 57. Managing the CacheManaging the Cache // clear cache for author ORMEvictEntity( "author" ); ORMEvictEntity( "author", 1 ); // clear cache for articles ORMEvictCollection( "author", "articles" ); ORMEvictCollection( "author", "articles", 1 ); // clear cache for HQL ORMEvictQueries( "mycachename" ); ORMEvictQueries();
  • 58. Advanced Use CasesAdvanced Use Cases Query: Retrieve distinct countries of all addresses in alphabetical order. SQL: HQL: Criteria API: select distinct country from address ordered by country select distinct country from address ordered by country criteria.setProjection(projections.distinct(projections.property("Country"))) criteria.addOrder(order.asc("locality"));
  • 59. ColdBox ORM ModuleColdBox ORM Module https://www.forgebox.io/view/cborm "This module provides you with several enhancements when interacting with the ColdFusion ORM via Hibernate. It provides you with virtual service layers, active record patterns, criteria and detached criteria queries, entity compositions, populations and so much more to make your ORM life easier! In other words, it makes using ORM not SUCK!"
  • 60. There is more!There is more! Convenience Methods Versioning Validation ORM Search Advanced Mapping Event Handlers (Interceptors)
  • 61. Online ResourcesOnline Resources Developing Applications Adobe ColdFusion ORM ColdFusion ORM Developer Guide CF-ORM Google Group Hibernate Documentation ORM Slack Channel on CFML Slack Team https://helpx.adobe.com/coldfusion/developing-applications/user-guide.html?topic=/coldfusion/developing-applications/morehelp/coldfusion-orm.ug.js http://adobe.ly/LnJilm http://groups.google.ca/group/cf-orm-dev http://www.hibernate.org/docs
  • 62. PublicationsPublications Java Persistence with Hibernate Adobe ColdFusion 9 Web Application Construction Kit, Volume 2: Application Development ColdFusion ORM http://www.manning.com/bauer2/ http://forta.com/books/0321679199/ http://www.coldfusionormbook.com
  • 63. Please submit your surveyPlease submit your survey for a chance to win!for a chance to win! Go to the ColdFusion Summit mobile app Find this session: D103: Let ColdFusion ORM do the work for you! Make sure you have registered for this session Select the “Survey” link at the bottom of the session and complete the survey Each survey has a chance to win $25 Amazon Gift Certificate
  • 64. Thank You!Thank You! Masha Edelen masha@hdwebstudio.com @mashaedelen