Streaming the JPA with Spring Boot
Accessing databases historically for every Java developer was a headache, but for the last decade (a little bit less), with the release of Spring JPA, it became much easier. And de facto, it became the standard for every modern Java Spring application. Yes, there are alternatives like MyBatis, jOOQ, or others, but the general usage of those is relatively small. The reason for the popularity is quite straightforward — the simplicity of usage, most of the configuration code is hidden from the user.
In this post, I will describe an extension to JPA to give users a choice and one more approach when it comes to working with the DB layer.
Overview
JPAstreamer is a lightweight extension for any JPA provider that allows the creation of Java Streams from database content. So let’s check out what can be done with it and how it can make coding better.
Implementation
Let’s start with a simple setup for gradle (maven is similar but gradle requires fewer characters :)
For the demonstration purpose, I will create three entities to represent the football team with Players and Stadium. For every team there are a bunch of players (one-to-many relation) and one stadium can be used by a few teams (greetings “San Siro”) (many-to-onr relation). Such relations and tables will be sufficient to demonstrate most of the cases.
For the entities, we need to create DTO (Data Transfer Object) to have a middle layer before the database. We need only few — simple TeamDTO, PlayerDTO and DetailedTeamDTO.
Before using JPAStreamer it needs to be initialized with the schema name or injected into the service, in this case Spring will take care of initialisation:
Let’s start with the simple query to get all teams sorted by name and mapped to our simple TeamDTO
Notice Team$ which is a class generated by the JPAstreamer library. The beauty of this approach is that the result returned by our JPA layer is already streamed and we can just apply our filters/mapping to it.
In a similar way, we can filter by some values when doing a query — find all players with a number of matches greater than:
For the final part let’s play around a bit with joining different entities. In order to perform the JOIN
operation with JPAstreamer
, we just need to specify the joining stream. By default JPAStreamer uses LEFT JOIN(returns all records from the left table, and the matching records from the right table), thus it can be customized in the joining method. In those parts, we can skip mapping the results to DTO to make a point on other parts.
As a start we can simply return all teams with their players mapped to the map:
For the ManyToOne relation, we can search for all players with name and their teams.
Conclusion
After playing around with this library I find it quite useful and am pretty sure I will use it for a number of projects as it makes querying database a little bit cleaner and more “stream” way, which looks better and simpler. I didn’t do any performance analysis, but taking into account that the library transforms the streams into native SQL queries it should not be impactful on a majority of the systems.
Keep coding and have one.
— — — — — — —
Level Up Coding
Thanks for being a part of our community! Before you go:
- 👏 Clap for the story and follow the author 👉
- 📰 View more content in the Level Up Coding publication
- 🔔 Follow us: Twitter | LinkedIn | Newsletter
🚀👉 Join the Level Up talent collective and find an amazing job