29
RETHINKING PERSISTENCE JPA/Hibernate & myBatis Compared

SeaJUG May 2012 mybatis

Embed Size (px)

Citation preview

Page 1: SeaJUG May 2012 mybatis

RETHINKING PERSISTENCEJPA/Hibernate & myBatis Compared

Page 2: SeaJUG May 2012 mybatis

04/11/2023 2

About Will• Will Iverson

• CTO, Dynacron Group

• Personal Background• Professional software

dev/architect/consulting since 1995• Roles: Apple, Symantec, SolutionsIQ• Clients: Sun, BEA, Canal+, T-Mobile,

at&t, Microsoft, State of WA• ORM Patent Case• 4 books, many articles

Page 3: SeaJUG May 2012 mybatis

04/11/2023 3

About Dynacron Group• Established mid-2010• Technology Consulting (Java, .NET, BI)• ~25 consultants (& growing, see site for info)• Key differentiation: Continuous Delivery

• People• Deep roots in Seattle region• TPM/ScrumMaster, Sr Dev, Sr SDET, DevOps

• Process• Blend of Agile (Scrum/Kanban/XP), heavy use of TDD, automation

• Tools• Leverage cloud in client friendly-way (e.g. start with testing)• Manage source & binaries (CI, automated release)

Page 4: SeaJUG May 2012 mybatis

Problem

• Need to save data• Preferably ACID!• No need to reinvent wheel

• Hand-crafted JDBC is annoying & error-prone• Code generation is… sort of ok…

• But runtimes are better

• Relational databases are pretty darn popular• Tools, extensive knowledge• Not going away any time soon

Page 5: SeaJUG May 2012 mybatis

Possible Solutions• JPA

• Really, Hibernate• myBatis• Spring JDBC

• Hybrid of myBatis approach + native JDBC…

• All others = essentially no adoption• Measured by # of downloads, search volume, job postings, etc…

• What about NoSQL…?• Cassandra, MongoDB, CouchDB…• http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis• MySQL makes an ok NoSQL (see SauceLabs post)

Page 6: SeaJUG May 2012 mybatis

Really Different Approaches• ORM (JPA/Hibernate)

• Generates SQL from object graph• Proxy objects• DOA if you can’t talk to the DB directly• Most popular choice (Hibernate)

• Mapping (MyBatis)• Make it easy to write and map result sets to Java

• All other (relational) frameworks are essentially noise in terms of market adoptions• As measured by # of downloads, search volume, job postings, etc…

Page 7: SeaJUG May 2012 mybatis

Hibernate

Application

Hibernate Session(1st Level Cache)

Hibernate2nd Level Cache

RDBMS

Hibernate Session(1st Level Cache)

Data

Data

DataProxy

DataProxy

Heart of the difference w/myBatis

• LazyInitializationException• SessionException• StaleSessionException• TransientObjectException• PersistentObjectException

Page 8: SeaJUG May 2012 mybatis

Comparisons

• Hibernate• Manual is 391 pages (and you will need a book)• Many dependencies• Based on JPA• Study the code for years and still be learning

• MyBatis• Manual is 73 pages (in a bigger font)• One tiny library• No standard• Code review in a day

Page 9: SeaJUG May 2012 mybatis

ORM Cool/Scary ExampleList result = session.createQuery( "from Event" ).list();for (Event event : (List<Event>) result ) { println(event.getDate() + “:" + event.getLocation() );}

Question: How much data, in how many queries, will this snippet of code result in?A: Impossible to tell from this snippet. Depends on many factors. Mapping configuration for Event, Location objects and associations, as well as the cache configuration. Fixing one code execution path, for example, eager fetching Location, will cause potential problems elsewhere. So, this could result in N*N, (N+1), 1, or even 0 requests.

Page 10: SeaJUG May 2012 mybatis

JPA• Graphs of objects in memory• Linked to corresponding data structures in RDBMS• Non-trivial examples require careful understanding of

entire structure• Promise: Learn JPA, never worry about SQL• Reality: Must have a VERY solid understanding of SQL,

Java, and JPA • In particular, the query and criteria APIs• Need to understand sessions and object scope as relates to

sessions

Page 11: SeaJUG May 2012 mybatis

Hibernate Session Complexity• What happens if object

accessed outside of session?

• Outside transaction?• Cache status?• Objects have LOTS of

hidden state associated• Proxy-based access

• Really, really complex if those objects are intended for presentation

• Web services• User interfaces

• Very complex serialization scenarios

Open Session

Close Session

Create Transaction

Commit Transaction

SQL StatementFlush

SQL StatementSQL Statement

SQL StatementFlush

SQL Statement

Transactio

n

Sessio

n

Page 12: SeaJUG May 2012 mybatis

MYBATIS EXAMINED

Page 13: SeaJUG May 2012 mybatis

Personal Interest

• Finished project that ran from 2008-2010• Numerous challenges (blend of team + Hibernate)

• Starting new project in 2010• Just needed to wrap a few sprocs

• Hibernate seemed like overkill

• Really liked the annotation-only approach• iBatis based on XML… XML is fine for config, but

dev? Bleah.

Page 14: SeaJUG May 2012 mybatis

Brief History

• Started as part of a JPetStore demo in 2002• iBatis 2.0 named & released in 2004

• Donated to ASF• Moved from ASF, renamed myBatis 3.0 in 2010

• Released via Google Code• Complete redesign (based on TDD, simplicity, etc.)

Page 15: SeaJUG May 2012 mybatis

MyBatis Approach

• Write queries in SQL• Map result sets to data objects via annotations• Get objects back

• (Optional) use generator• (Optional) cache result sets

• …

• That’s basically it.

Page 16: SeaJUG May 2012 mybatis

Basic Design

Application

RDBMS

SessionMapper

Interfaces

Page 17: SeaJUG May 2012 mybatis

Key Concepts

• Configuration• Mappers• Code

Page 18: SeaJUG May 2012 mybatis

Configuration (Conceptual)

• Session Factory• Static, thread-safe factory• Attach mappers at bootstrap

• With annotations, mappers are just interfaces with annotations

• With Spring, easy drop mapper interface into context

Page 19: SeaJUG May 2012 mybatis

Mappers

• XML or Annotations• Annotations = simple interfaces w/annotations (no implementation!)

public interface UserMapper {@Insert({ "insert into user (nickname, email) values (#{nickname},

#{email})" })@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);

@Select("select count(*) from user")long count();

@Delete({ "delete from user where id = #{id}" })void deleteById(User user);

}

Page 20: SeaJUG May 2012 mybatis

Usage

• Simply ask the session for mapper instance• Call method & get data

• Begin transaction, commit, and rollback handled once via standard utility wrapper• (e.g. Spring or custom)

user = session.getMapper(UserMapper.class);return user.count();

Page 21: SeaJUG May 2012 mybatis

Available Annotations

• Cache (support for wide variety)• Mappings (result set -> Java object[s])• Identifier mapping• Static statements• Dynamic statements• Parameters

Page 22: SeaJUG May 2012 mybatis

Other Features

• Generator (demo)• Migrations (discuss if time)

• Maven plugin• Integrations

• Spring, Guice, Scala• OSCache, EhCache, Hazelcast

Page 23: SeaJUG May 2012 mybatis

Things You Don’t Do With MyBatis

• Don’t Do• Object proxies• Complex object lifecycles

• Could Do (But Don’t)• Build highly complex mapping graphs

Page 24: SeaJUG May 2012 mybatis

ComparisonTopic JPA/Hibernate myBatis

Developer productivity

Java, SQL, HQL, Criteria Java, SQL

Caching strategies Two level cache One level cache

Debugging Complex Simple (except for more complex mappings, which are localized)

Transaction management

One transaction per session w/open-session-in-view only sane route: Spring TX = insanity

Ironically, easier to use with Spring TX.

Schema management Built-in validation. Upgrade but not real migrations

Real migrations (but requires hand-rolling)

Session Management Open-session-in-view only sane route

Open-session-in-view, or not (simplified object lifecycle)

Page 25: SeaJUG May 2012 mybatis

Thoughts: Hibernate/JPA vs. MyBatis

• MyBatis is much, much simplier• Hibernate/JPA require learning HQL

• Criteria queries are better for simple things

• In practice, this means you have three data APIs, SQL, Criteria & HQL• HQL only for hard stuff• Find it much faster to just knock out

query in SQL, pop in annotation and call it good

• People don’t use most of Hibernate• Don’t understand complex

mappings• Miss a lot of the benefit

• Sessions & Object attachment in Hibernate/JPA is very complex• Two different cache levels, objects

may or may not be attached to session – at runtime often feels non-deterministic

• Most missed from Hibernate• Bootstrap validation of expected

schema

Page 26: SeaJUG May 2012 mybatis

MyBatis Negatives?• Over apx 1 year project, asked several people on team

for thoughts• Only cited issue was compatibility with legacy stored

procedure• Team was unable to diagnose why sproc wouldn’t load into

mapping• Worked around by updating sproc• Everyone agreed MyBatis was much simpler & easier to use

• Really liked the Spring integration• 1 person cited Spring JDBC as pretty darn easy too

Page 27: SeaJUG May 2012 mybatis

Job Trends

Page 28: SeaJUG May 2012 mybatis

Job Trends (Detail on Smaller)

Page 29: SeaJUG May 2012 mybatis

DEMOCode for demo up on GitHubhttps://github.com/dynacron-group/