Domain entities should be free of persistence concerns
Well, that’s exactly what MyBatis does. Entities are POJOs that know nothing about persistence (see here). Instead you teach MyBatis how to save and retrieve these entities using SQL statements and result maps (see here). For trivial objects, you don’t even have to define result maps, MyBatis figures them out automatically.
Give me control over SQL
For any serious project that uses a relational database, you can’t escape learning SQL. Most ORMs try to insulate you from SQL by providing higher level abstractions. However in exchange, they force you to learn a new API or an abstract query language. These APIs/query languages generate SQL anyway, so the only difference is that you don’t know what they are generating until you pop open the hood. In many cases, a query that I can write in a single statement, will be generated in two or more statements, reducing performance. Now I am suddenly going back to the ORM and tweaking it to produce a more efficient query. Sometimes the API is not rich enough to do everything I want, and I have to escape into SQL land anyway. Why bother with all this? If I have to know SQL anyway, why not just write it myself and optimize it directly? Teaching the framework to map the result into objects is much easier.
Guess what, that’s exactly what MyBatis does – see the result map here. It teaches MyBatis how to map a query result in to a Transaction object with references to an Account and a Category. I end up with much cleaner and understandable code.
Here are the two projects I used for comparing MyBatis to other ORMs: