What is Mybatis
- Mybatis is a Persistence Framework which acts as a mediator between Application layer and Database
- In Java applications, the persistence layer involves populating Java objects with data loaded from the database using SQL queries, and persisting the data in Java objects into the database using SQL.
- Most of the Traditional ORMs (Ex. Hibernate) map Java Objects to Database tables, Mybatis maps Java Methods to SQL Statements.
- MyBatis couples objects with stored procedures or SQL statements using a XML descriptor
Benefits of Mybatis
- Light Weight…Only one JAR or Maven – Dependency Entry needed in Project
- ResultMap:Most Powerfull feature of Mybatis
- Dynamic SQL
o | If |
o | choose (when, otherwise) |
o | trim (where, set)
for Each |
- Transaction Manager
- JDBC : tranditional JDBC Transactions
- Managed : J2EE Container Managed
Mybatis over JDBC
- Eliminates Lot of Common JDBC code
- ·Eliminates Responsibility of transaction management from hands of Programmers
- Using ResultMap, any complex ResultSet can be converted to Object ·
- Supports Dynamic SQL which would have been done through String concatenation or If/Else in JDBC ·
- Uses PREPARED statement as Default ·Local Cache supports cache management at transaction level ·Transaction Management using Mybatis-Spring
Mybatis over Hibernate
Point | MyBatis | Hibernate |
Size | Lightweight | Comparatively larger in Size |
Learning Curve | Low Learning Curve | Higher Learning Curve |
Programming | Uses SQL, so is DB Programming | Uses HQL, Independent of DB, Easy to |
Return Type | Maps ResultSet from JDBC API to POJO | Maps Java Objects to Database Tables |
USPs | More Fetch Centric | More Persistence Centric |
Table Vs POJO Mapping | No orm impedance mismatch, until required , Result map doesn’t need to be refreshed | Tightly coupled, Ex. any column in table needs to updated in POJO immediately |
Caching
MyBatis has inbuilt support for caching SELECT query results within the scope of SqlSession level ResultSets. In addition to this, MyBatis also provides integration support for various third-partycache libraries, such as EHCache, OSCache,and Hazelcast.
MyBatis has two layers of caching:
Local Cache Local Cache is always enabled.
It has two Scopes , Session and Statement where Session is default.It is actually a MAP which contains below Key and Value.
key = (mybatis-namespace + stmt-name) + (raw sql including parameter placeholders) + (actual SQL parameter values)
value = (list of Java objects resulting from that query)
When localCacheScope=STATEMENT then the cache is cleared at the end of each MyBatis statement.
When localCacheScope=SESSION, then the cache is cleared:
- at the end of the current transaction (or end of each statement when autoCommit=true)
- whenever any insert/update/delete statement is executed
Second Level Cache
- Shares data between transactions
- By default, returns a copy of the cached object created via serialize/deserialize – which requires all cacheable objects to implement Serializable
- Can hook into “enterprise” caching systems, or use a simple in-memory cache. Thein-memory approach works only when the DB is exclusively updated by a single process
By default, flushes the entire cache whenever an <insert>, <update> or <delete> MyBatis statement is executed.
Keys cache entries by the same key for the local cache, ie a string built from (mybatis- namespace + stmt-name) + (raw sql) + (actual parameter values)
Conclusion
Local Cache stores data till duration of transaction, hence it is good.However it wont be much helpful with optimizing read-only or master data.For optimization, Second level cache should be used.
Transaction Management with Mybatis-Spring
It uses existing DataSourceTransactionManager from Spring.
It can be used using Spring’s @Transactional annotation.
Container Managed Transactions
Leave Responsibility of transaction management with J2EE Container
Programatic Transaction Management
Spring will handle your transaction (Sample code below, how to handle transactin)
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = txManager.getTransaction(def);
try { userMapper.insertUser(user);
// Inserting into table using Mybatis Mapper
}
catch (MyException ex) { txManager.rollback(status); throw ex;