Spring Data JPA # 1 – Overview and concepts

Tram Ho

Part 1. Repository

1.1. Introduce

Building and implementing the data access layer in applications sometimes causes a lot of trouble for the programmer due to its cumbersome and complex. Although there are now many libraries and frameworks supporting it, we still cannot avoid rewriting too much pre-written code in libraries, and our code will become more and more “messed” . To minimize the impact of the above problem, Spring provides us with a solution that is abstract reposity , they are designed based on interfaces, significantly reducing pre-written code and the impact of having to execute too much. layers in the data access layer.

1.2. Core concepts

The most basic and core part of the Spring Data abstract repository is an interface called Repository , which accepts an Entity class corresponding to the java class representing a table in our database, and the data type of the ID field. in that table. This interface provides several functions that revolve around the CRUD entity it manages, as follows:

Spring Data also provides us with some interfaces with features suitable for each purpose, and they all inherit from the Repository interface above. Below is an example of an abstract repository that allows the sort and paging of data retrieved from the database:

For example of PagingAndSortingRepository , to access the second page with the length of a page of 20 lines, we could do the following:

Note: Here are some Spring Data interfaces available to us in the tree diagram:

1.3. Query methods

To create an abstract repository with Spring Data will basically include the following 4 steps:

  • Declare an interface that extends from one of the available interfaces depending on the purpose.public interface PersonRepository extends JpaRepository<User, Long> { … }
  • Declare the query methods in the interface.List<Person> findByEmail(String email);
  • Configuration tells Spring that this is a repository and initializes it. (Here I use Repository anotation, you can also configure with .xml file)
  • Inject bean of repository and use.

Above I have provided the basic steps to create a repository, let’s go ahead and explore the details of each of the steps mentioned above!

1.3.1. Define repository interfaces

In the first step when creating a repository, you will have to define an entity class for that repository to recognize and work with. The Repository will receive the entity class and kiểu dữ liệu của ID trong entity class , then we will have the CRUD methods of the Repository matching our entity class.

1.3.2. Defines query methods

1.3.2.1. Query lookup strategies

Next, we will discuss the definition of query methods . In general, there will be two ways for the repository to be able to identify the query to the database you want through the method name . The first is to get a query directly from the method name in the repository. The second way will use some additional options from the Spring Data Framework to create the query. You can choose one of two ways depending on the actual purpose, but Spring also offers some strategies to help you do that, it is called query-lookup-strategy following 3 options. :

  • CREATE – If this option is used then the Spring framework will attempt to automatically generate a query from the query method name.
  • USE_DECLARED_QUERY – For this option the Spring framework tries to find a declared query, either by anotations or declared by other means. If the repository cannot find it, it will error at runtime.
  • CREATE_IF_NOT_FOUND (default) – This is the default option and it combines CREATE and USE_DECLARED_QUERY. It looks for a pre-declared query and if no declared query is found, it generates a query based on the custom method name.
1.3.2.2. Query creation

Spring helps us to generate query methods from the name of the methods in the repository, starting with the prefixes representing the purpose of the query to be executed. For example findBy, find, readBy, read, getBy, ... , and the rest will be modern for variables in the entity class, we can concatenate them with keywords like And, Or, ... as follows:

In this example, Spring will parse the EmailAddressAndLastname (called the attribute expression) and generate us the query with two properties, address and lastname . As you can see, And has been used in this example to make our method name clearer. In addition, you can also use other keywords like: Between, LessThan, GreaterThan, Like for attribute expression.

With the help of keywords, our method name becomes clearer and easier to understand, however in some cases we want an expression to still make that clear but cannot use keywords like As mentioned above, so how can Spring understand our purpose to generate queries with the best purpose? Let’s go to the next example to clarify how Spring analyzes property expressions.

Assuming I have an entity class in which a variable is address with data type ZipCode and I want to find all the records by the parameter zipCode passed, at this point I will create a method like this: List<Person> findByAddress(ZipCode zipCode); . As far as the theory was concerned, this is a very clear attribute expression and in practice it also performs very well. However, to make it easier for the other members to look at it, I want to fix it as:

The problem here is that when I add ZipCode to the method name, will Spring misunderstand that I am looking for the zipCode property? The answer here will be no and the method I just edited will still work as well as the original method.

Spring’s algorithm will find the AddressZipCode expression in the entity class, if it does, it will accept this expression as an attribute and create a query for it. On the contrary, Spring will separate our property expression from right to left and follow the Camel Case style words (words with capital letters) and divide them into head and tail, then it will try to find these parts in the entity class (prefer the first one). This time it will be AddressZip, Code . There is no right, the algorithm continues to Address, ZipCode . Thus, Spring has found the Address for the query and determined this will be the property to look for, then get the tail to further separate.

The new problem that will happen in this case is when in our entity also exists a variable named addressZip , so the above method will not work as we expected. To solve this problem, we can separate the keywords with the _ sign, then Spring will separate exactly the way we want:

1.3.2.3. Query data

Spring provides us the @Repository @Repository help annotate the class to become a repository, through which Spring can recognize and create a repository bean for us when launching the application. Then we just need to inject bean and use the following:

Conclusion

So, through this article, I have gone through the concepts and how Spring Data generates query command from the method name for us, in the following article I will introduce to you another feature of Spring Data. We actively create queries that retrieve data from the database, which is the Spring Specification. See you in the following article!

Share the news now

Source : Viblo