killing shark-riding dinosaurs with orm

50

Upload: ortus-solutions-corp

Post on 15-Apr-2017

881 views

Category:

Technology


0 download

TRANSCRIPT

ColdFusion ORM

More awesome than a dinosaur riding a shark with a laser!With pink unicorns!

WHO AM I?

• Luis Majano - Computer Engineer

• Imported from El Salvador----------->

• Architecture + Software Design

• CEO of Ortus Solutions

• Adobe Community Professional

• Creator of all things Box: ColdBox, ContentBox, CommandBox,WireBox….

AGENDA

• Thought experiment• Silver Bullet• Benefits• Advice from Special Guest• Specialized ORM Services

Thought experiment?

CF ORM was easier to use?

OO way to query

ORM was fast80% of API Querying

Extensible way to finish the remaining

20%

I ate too much today!

Auto build relationships

CONCLUSIONS

• Can’t or doesn’t exist• Sounds like bull…..• What’s this latino up to? Is he trying to get my money

PROVE IT!

ORM is NOT a silver bullet

• Just another tool• Times you need the power of the database: reports, legacy, sp, etc.• Mix and match• What if you wanted array of structs, or lists or queries or arrays of data?• There is a learning curve, but it is worth the investment

Applied Benefits• Increase in productivity of about 40%• Rich Object Models• Deliver DB patching updates• Increased Flexibility• Great for abstracting vendor specific

intricacies• OO Queries• Avg JDBC <10ms of about 350K

Transactions

How do we start?

coldfusionormbook.com amazon

Guru ORMLui

10 keys to ORM Success!

#1: OO Modeling is Key

• ORM relationship modeling is key• OO is required• UML is your best friend• STOP THINKING ABOUT DATA• YOU ARE NOT MODELING A DATABASE

#1: OO Modeling is Key

#1: OO Modeling is Key

Query Object

Data Data + Behavior

#2: Engine Defaults Not Great!• Do not use the CF engine defaults:

• FlushAtRequestEnd (false) • Send to Database no matter what

• AutoManageSession (false)• Use transaction demarcations

• Cascade• Lazy• Batches• Caching• Relationship Fetching (Many to One - Select instead of Join)• Dialect (Choose it if possible)

#2: Engine Defaults Not Great!• cfclocation

• Use it to a specified directory, else pay the price• logSQL

• Great for debugging, OFF for production, else pay the price• Having Issues?

• saveMapping

• DataBoss - ortussolutions.com/products/databoss

#3: Understand Hibernate Session

• Not the same as session scope• A transitionary space

• entityLoad()• entityNew() ?

• A caching layer• You need to control when to send to DB• You can remove entities from it and clear it• You can attach a secondary cache to it

#3: Understand Hibernate Session

Hibernate Session (Conversation - Request)

DB

Eu

Ex EzEy

Cache ehCache/

CouchbaseBatched SQL

EntityNew()EntityLoad()

Data (!CFCs)

Hibernate Session Factory (application)

CRUD

When?

ORMClearSession()

#3: Understand Hibernate Session

DBSyncInsertionsinorder

updates

Collectiondeletions

collectiondeletion,updates,inserts

collectioninsertions

deletionsinorder

#4: Transaction Demarcation

• Transactions demarcate SQL boundaries• Important Imperative for ORM + SQL• No communication to DB should occur without one• Reactive programming, expect the worst• cftransaction or Hibernate transactions

#4: Transaction Demarcation

• Transaction Theory:

• Any existing ORM session is flushed and reused• Data can be committed or rollback• ORMFlush() does not work in a transaction block• If commit, then flushed to database• If rollback, session is cleared

#5: Lazy Loading is KEY• You will fail if you do not use this!• Performance will SUCK!• Always Use It!• Lazy Types:

• True = Only when you call getXX (all types)

• Extra = Loads proxy objects with primary keys only (o-2m,m-2-m)

• Proxy = Loads proxy object with primary key only (o-2-o, m-2-o)

• fetch=“join”

• Uses a single SQL query, great for performance• batchsize

• For performance, like pagination for objects

#6: Avoid bi-directional

• They can be more of a headache• Cascading Deletes• Inverse

• Does it make sense?• Supporting methods for bi-directional linkage• Supporting methods for un-linkages

#6: Avoid bi-directional

#6: Avoid bi-directional

#7: Do not store entities in scopes

• Don’t do it!• No linkage to Hibernate Session• Relationships will fail if not lazy• entityMerge()

• Store ID’s instead

#8: Use DB Indexes

• #1 Performance Problem• Identify relationships• Identify HQL, SQL• Learn them• property name=“isActive” index=“idxActive”

#9: Cache = BOOST!

• Don’t go cache crazy• Develop a strategy• Does not store CFC, stores individual property values• Use distributed caches: ehcache, couchbase• You can cache:

• Entity property data : Only caches properties data values• Entity association data : Only caches primary keys• Query data : HQL, ORMExecuteQuery()

• Evictions:• ORMEvictEntity(), ORMEvictCollection()

#10: OO Modeling is Key

• ORM relationship modeling is key• OO is required• UML is your best friend• STOP THINKING ABOUT DATA• YOU ARE NOT MODELING A DATABASE

ORM Module

install cborm

ORM Module

Base ORM Service

Virtual ORM Service

Active Entity

Entity Populators

Validation

Event Handlers DI/AOP

Base ORM Service

• Service layer for any entity• OO Querying, caching, transactions• Dynamic finders, getters, counters• Object metadata & session management• Exposes more features from Hibernate• 90% Foundation

• Extends Base ORM Services

• Roots itself to a single entity = Less Typing

• You can build the 10%

Virtual/Concrete ORM Services

• Active Record Pattern• Sweet validation integration• DI/AOP Available

Active Entity

• Populate Entities: xml, json, queries, structs• Compose relationships from simple values• Null support• Exclude/include fields

• Server side validation• Dependency Injection Listeners• Custom Event Driven Programming

Entity Populators

Validation

Event Handlers

ORM Utilities

ORM Services in Action

box install cartracker-demo

Base ORM Service

• count(), countWhere()• delete(), deleteAll(), deleteByID(), deleteByQuery(), delete Where()• evict(), evictEntity(), evictQueries()• executeQuery(), list()• exists()• findAll(), findAllWhere(), findByExample(), findIt(), findWhere()• get(), getAll(), • getKey(), getPropertyNames(), getSessionStatistics(), getTableName()• clear(), merge(), new(), refresh()• populate(), populateFromJSON(), populateFromXML(), populateFromQuery()• save(), saveAll()

Base ORM ServiceDynamic Finders/Counters

• Expressive Programming• Three types of dynamic Finders/Counters

• findBy : find ONE entity• findAllBy : find ALL entities• countBy: Give you a count

Base ORM ServiceDynamic Finders/Counters

• Method Expressions

• Conditionals

• LessThanEquals, LessThan• GreaterThanEquals, GreaterThan• Like• Equal, NotEqual• isNull, isNotNull• Between, NotBetween• inList, notInList

• Operators

• And• Or

• Query Options

• ignoreCase, timeout, max, offset• cacheable, cachename

Criteria Builder

Awesome OO Queries

Criteria Builder

• Limitations of CF ORM:• entityLoad() has limited features• Some operations we always need an entity = slow• What if I want arrays, or arrays of structs• Complex relationships are hard to query• SQL/HQL string build is so 90’s == NOT FUN!

Criteria Builder

• Programmatic DSL Builder• Rich set of criterias• Projections and Result transformations• Subqueries• Caching• SQL Inspections & Debugging• Array of structures is twice as fast as queries

Criteria Builder

Criteria Builder

• Request new criteria• newCriteria()

• Add simple restriction(s)• Find all cars sold between April and July• Use between()

• Get results• Use list( max, offset, timeout, sortOrder, ignoreCase, asQuery )

• Get counts• Use count()

Criteria BuilderRestrictions

• between()• eq()• gt()• ge()• gtProperty()• isEmpty()• isNull()• ne()• ilike()

• and()• or()• not()• conjunction()• disjunction()• isTrue()• isFalse()• sqlRestriction()• ...much more!

Criteria BuilderRetrievals

• Retrieval

• firstResult()• get()• list()• count()

• Options

• fetchSize()• readOnly()• maxResults()• cache(), cacheRegion()• timeout()• order()

Criteria BuilderAliases -> Joins

• Allows you to do queries within relationships

• Creates SQL Joins• Aliases can be nested, so if your entity

knows about it, you can query it!

Criteria BuilderProjections

• Projects change nature of results• Arrays of data, or arrays of structs (Mighty Fast)• Once its added its there forever

• avg• count• countDistinct• distinct• groupProperty• max• min

• property• sum• rowCount• id• sqlProjection• sqlGroupProjection• detachedSQLProjection

Criteria BuilderDebugging + Logging

• Application.cfc• ormsettings.logsql = Never in production

• Criteria Builder SQL Inspector

• startSQLLog( returnExecutableSQL, formatSQL )• stopSQLLog()• getSQLLog()• getSQL( returnExecutableSQL, formatSQL )

Thanks!

Q & A

ortussolutions.com/odw