Deep dive on spring boot and data JPA implementation: A to Z
According to Spring documentation
Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA-based repositories. This module deals with enhanced support for JPA-based data access layers. It makes it easier to build Spring-powered applications that use data access technologies.
What will we learn here
- Spring boot with data JPA setup with Gradle and H2 database
- Save, update and delete object into the table
- Retrieve data from a table using JPA default way, projection, and custom query
- Integrate pagination on JPA
1. Setup of JPA & H2 Database
Here, we will use H2 database because this is a Very fast, open-source, in-memory database. H2 is a relational database management system written in Java. It can be embedded in Java applications or run in client-server mode. No external database required to setup. For the production environment, you can add other databases that you required.
You need to add bellow dependencies in your build.gradle file
Here, you need spring-boot-starter-data-jpa for JPA and com.h2database:h2 for H2 database
Now you have to configure H2 database. It is also simple. Add bellow lines into application.properties file
Here, database name = testdb
Driver name = org.h2.Driver
username = sa and password = password
Dialect = H2Dialect
Here, H2 database is an in-memory database, so after each run of application all data will erase
That's it. Your application, JPA, and database are ready. Now we will design an Entity.
2. Entity design and save, update and delete
For our example purpose, we will create a table named “customer” and the Entity class name is “Customer”. This entity is given bellow
Here, we have 7 fields in the table and id is primary key and auto-increment. For another relational database, you have to add a table name and schema name.
Now we have to add the repository for this entity. We will retrieve data using the repository. Here Repository class is like bellow:
Here, we are using CrudRepository so we can access 10 default interface methods like save, findAll, etc from this class. Here, for each function, JPA and Hibernate play the actual game. They actually generate database queries and fetch data based on this query. Also, they generate queries based on the database driver defined in application.properties
Save/Update Customer in table
For savings data into a table, you have to just build an object and call the repository save function. Here is the code:
Here, we are building Customer objects based on logic. If an object has no ID then we are building an object and saving it otherwise we are just updating it.
During save it is generating bellow like query :
(id, first_name, gender, last_name, mobile_number, present_address, permanent_address)
(null, ?, ?, ?, ?, ?, ?)
Fetch Data based on mobileNumber
Here, I am searching for customers based on mobileNumber. JPA query is
List<Customer> findAllByMobileNumber(String mobileNumber);
After execution of this code the actual query is like below:
2021–03–24 00:31:49.104 INFO 10713 — — [nio-8081-exec-6] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
customer0_.id as id1_0_,
customer0_.first_name as first_na2_0_,
customer0_.gender as gender3_0_,
customer0_.last_name as last_nam4_0_,
customer0_.mobile_number as mobile_n5_0_,
customer0_.present_address as present_6_0_,
customer0_.permanent_address as permanen7_0_
Fetch Specific column from the table
In the upper example, it is selecting all columns from the table. What if we want just some specific field like ID, firstName, lastName, and mobileNumber only. How can get this? We can achieve this in bellow way:
- Using projection
We have to create an interface with the getter of specific fields. It is given below:
Now your JPA query is like:
List<ICustomer> findAllByFirstName(String firstName);
Now the actual query will be
customer0_.id as col_0_0_,
customer0_.first_name as col_1_0_,
customer0_.last_name as col_2_0_,
customer0_.mobile_number as col_3_0_
Here, it is selecting only our desired fields. It will save our RAM and unnecessary data.
2. Using EntityManager and native query
Using entity manager we can easily execute the native SQL. This code will like bellow:
3. Pagination based query
In Spring data JPA we can easily integrate pagination. The Pageable Interface has the below properties :
Now our query is like below
Page<Customer> findAllByLastName(String lastName, Pageable pageable);
Here, input is lastName and pageRequest and output is Page of the customer. I am explaining what it means.
In pageRequest it’s basic parameter is : pageSize and pageNumber.
If pageSize = 2 and pageNumber = 0 Then it will return the first two records from the database which is in ascending order.
If pageSize = 2 and pageNumber = 1 Then it will return the third and fourth two records from the database which is in ascending order.
From this response in “content” array, you will get your list of customers, in totalElements you will find total no of elements and in totalPages you will get the number of page exists based on current pageSize
Github link of this codebase is here
Controller Name : CustomerController
Service Name: CustomerServiceImpl
Repository Name: CustomerRepository
Domain Name: Customer
Hope this will help you. Thanks in advance.