It’s implementation from Repository pattern:
by Edward Hieatt and Rob Mee
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
The project jkniv-whinstone define the repository contract between you service layer and the database through the interface net.sf.jkniv.whinstone.Repository. There are four repository flavors:
The High-level design:
The whinstone repository interface it’s simple and very ease to use, it establish a contract for the Repository pattern, with the advantage that you can programmer using different databases (Oracle, PostgreSQL, etc) or APIs (JDBC, JPA) the same way. The learning curve to use jkniv-whinstone is very low because you don’t need to learning another query language like Criteria, JOOQL etc, understand a simple API with automatic binding and coding faster.
The steps to start are:
No annotations, no mapping (except if you want to use JPA), easily to test. The power of the database query language is yours and whinstone gives to you the plain java objects with automatic bind to input parameters and result set output, reducing a boilerplate of code to set JDBC parameters and ResultSet getters.
It’s very seductive write a query and someone (framework) translate to my specific database like HQL, JPQL, jOOQ DSL, etc. But there is the trap from lowest common denominator that could hug that framework. It’s probable that a lot of extra java code is necessary to do the same without the native query from your database.
The whinstone approach keep the power of database query language and your java code become more maintainable naturally.
These queries make the same for NoSQL Cassandra and a Relation Database SQL with PARTITION BY:
// cassandra query (Partition key -> acct_id, event, evt_date) SELECT acct_id, event, evt_date, tag_code FROM TRACKABLE_DATA PER PARTITION LIMIT 1; // SQL with PARTITION BY SELECT * FROM (SELECT acct_id, event, evt_date, tag_code, row_number() OVER (PARTITION BY acct_id, event, evt_date ORDER BY acct_id, event, evt_date desc) rnum FROM TRACKABLE_DATA) tablerank WHERE tablerank.rnum = 1 // Java code, naturally simple Queryable query = QueryFactory.of("events"); List<Event> events = repository.list(query);
You can use the best of your database without waste time to learn new framework query language, DSL or anything else.
The Repository interface have a simple set of methods to manipulate the data from/to database.
The library is 100% protected against SQL injection because all statements are PreparedStatement, except to couchdb that access is over HTTP protocol.
Version | whinstone Features | whinstone-jpa2 | whinstone-jdbc | whinstone-cassandra | whinstone-couchdb |
---|---|---|---|---|---|
0.6.x version | Auto Bind Parameters | ||||
0.6.x version | Auto Bind Result | ||||
0.6.x version | One-to-One | (native) | |||
0.6.x version | One-to-Many | (native) | |||
x.x.x version | Many-to-Many | (native) | |||
0.6.x version | JSR Bean Validation | ||||
0.6.x version | Transaction | ||||
0.6.x version | Paginate Query | ||||
0.6.x version | Retrieving auto-generated keys | ||||
0.6.x version | Bulk Commands | ||||
0.6.x version | Callback Methods | ||||
0.6.x version | Query Cache | ||||
0.6.x version | Converter Annotation | (jpa) | (jackson) | ||
0.6.x version | Jdk8 Timers | ||||
0.7.0 version | Query Statistics | ||||
0.7.0 version | Batch Commands | ||||
0.7.0 version | Triggers Events | ||||
0.7.0 version | Stored Procedure |