Killing Shark-Riding Dinosaurs with ORM
-
Upload
ortus-solutions-corp -
Category
Technology
-
view
881 -
download
0
Transcript of Killing Shark-Riding Dinosaurs with ORM
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
#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
#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
#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
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
• 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
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
• 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
• 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 )