SeaJUG May 2012 mybatis

Preview:

Citation preview

RETHINKING PERSISTENCEJPA/Hibernate & myBatis Compared

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

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)

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

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)

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…

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

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

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.

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

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

MYBATIS EXAMINED

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.

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.)

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.

Basic Design

Application

RDBMS

SessionMapper

Interfaces

Key Concepts

• Configuration• Mappers• Code

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

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);

}

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();

Available Annotations

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

Other Features

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

• Maven plugin• Integrations

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

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

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)

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

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

Job Trends

Job Trends (Detail on Smaller)

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

Recommended