Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use JPA correctly in Spring Boot

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail how to correctly use JPA in Spring Boot. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.

A basic JPA: common operations

1. Correlation dependence

We need the following dependencies to support us in completing this part of the study:

Org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java runtime org.projectlombok lombok true Org.springframework.boot spring-boot-starter-test test

two。 Configure database connection information and JPA configuration

The configuration option spring.jpa.hibernate.ddl-auto=create needs to be mentioned separately in the following configuration.

There are four common options for this property:

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Create: each restart of the project will re-innovate the table structure, resulting in data loss

Create-drop: every time you start a project, create a table structure and close the project to delete the table structure.

Update: update the table structure each time you start the project

Validate: verify the table structure, do not make any changes to the database

However, it is important not to use ddl to automatically generate table structures in a production environment. Handwritten SQL statements are generally recommended to do these things with Flyway.

Spring.datasource.url=jdbc:mysql://localhost:3306/springboot_jpa?useSSL=false&serverTimezone=CTT spring.datasource.username=root spring.datasource.password=123456 # print out the ENGINE of the table created by the sql statement spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create spring.jpa.open-in-view=false # is InnoDB spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL55Dialect

3. Entity class

We added the @ Entity annotation to this class to indicate that it is a database persistence class and configured the primary key id.

Import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @ Entity @ Data @ NoArgsConstructor public class Person {@ Id @ GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; @ Column (unique = true) private String name; private Integer age; public Person (String name, Integer age) {this.name = name This.age = age;}}

How to check that you have completed the above three steps correctly? Very simple, run the project, view the data if you find that the console prints out the sql statement to create the table, and the table in the database is really created, you have successfully completed the first three steps.

The sql statement printed on the console looks like this:

Drop table if exists person CREATE TABLE `person` (`id` bigint (20) NOT NULL AUTO_INCREMENT, `age` int (11) DEFAULT NULL, `name` varchar (255) DEFAULT NULL, PRIMARY KEY (`id`) ENGINE=InnoDB DEFAULT CHARSET=utf8; alter table person add constraint UK_p0wr4vfyr2lyifm8avi67mqw5 unique (name)

4. Create a Repository interface to operate the database

@ Repository public interface PersonRepository extends JpaRepository {}

First of all, the interface is annotated with @ Repository, indicating that it is related to database operations. In addition, it inherits the JpaRepository interface, and JpaRepository looks like this:

@ NoRepositoryBean public interface JpaRepository extends PagingAndSortingRepository, QueryByExampleExecutor {List findAll (); List findAll (Sort var1); List findAllById (Iterable var1); List saveAll (Iterable var1); void flush (); S saveAndFlush (S var1); void deleteInBatch (Iterable var1); void deleteAllInBatch (); T getOne (ID var1); List findAll (Example var1); List findAll (Example var1, Sort var2);}

This shows that as long as we inherit JpaRepository, we have JPA to provide us with good methods such as addition, deletion, modification, paging query and query according to conditions.

4.1 JPA has its own method in practice

1) add, delete, modify and check

1. Save users to database

Person person = new Person ("SnailClimb", 23); personRepository.save (person)

The save () method corresponds to the sql statement: insert into person (age, name) values (23, "snailclimb")

two。 Find users according to id

Optional personOptional = personRepository.findById (id)

The sql statement corresponding to the findById () method is: select * from person p where p.id = id

3. Delete users according to id

PersonRepository.deleteById (id)

The corresponding sql statement of the deleteById () method is: delete from person where id=id

4. Update user

The update operation is also implemented through the save () method, such as:

Person person = new Person ("SnailClimb", 23); Person savedPerson = personRepository.save (person); / / Update the name of the person object savedPerson.setName ("UpdatedName"); personRepository.save (savedPerson)

Here the save () method is equivalent to the sql statement: update person set name= "UpdatedName" where id=id

2) query with conditions

The following methods are customized according to the syntax provided by JPA, and you need to write the following methods into PersonRepository.

If we want to find Person based on Name, you can do this:

Optional findByName (String name)

If you want to find someone older than a certain value, you can do this:

List findByAgeGreaterThan (int age)

4.2 Custom SQL statement

Many times it is very useful for us to customize sql statements.

Look for Person based on name:

Query ("select p from Person p where p.name =: name") Optional findByNameCustomeQuery (@ Param ("name") String name)

Person partial attribute query to avoid select * operation:

Query ("select p.name from Person p where p.id =: id") String findPersonNameById (@ Param ("id") Long id)

Update Person name according to id:

@ Modifying @ Transactional @ Query ("updatePerson p set p.name =? 1 where p.id =? 2") void updatePersonNameById (String name, Long id)

4.3 create an asynchronous method

It is also convenient if we need to create asynchronous methods.

The asynchronous method returns immediately when it is called and is then submitted to the TaskExecutor for execution. Of course, you can also choose to get the result before returning it to the client. If you are interested in SpringBoot asynchronous programming, you can read this article: "SpringBoot Asynchronous programming Guide that beginners can understand."

@ Async Future findByName (String name); @ Async CompletableFuture findByName (String name)

5. Test class and source code address

Test class:

@ SpringBootTest @ RunWith (SpringRunner.class) public class PersonRepositoryTest {@ Autowired private PersonRepository personRepository; private Long id; / * Save person to database * / @ Before public void setUp () {assertNotNull (personRepository); Person person = new Person ("SnailClimb", 23); Person savedPerson = personRepository.saveAndFlush (person); / / Update the name of the person object savedPerson.setName ("UpdatedName") PersonRepository.save (savedPerson); id = savedPerson.getId ();} / * * find person * / @ Test public void should_get_person () {Optional personOptional = personRepository.findById (id); assertTrue (personOptional.isPresent ()); assertEquals ("SnailClimb", personOptional.get (). GetName ()) AssertEquals (Integer.valueOf (23), personOptional.get (). GetAge ()); List personList = personRepository.findByAgeGreaterThan (18); assertEquals (1, personList.size ()); / / empty database personRepository.deleteAll () } / * Custom query sql query statement to find person * / @ Test public void should_get_person_use_custom_query () {/ / find all fields Optional personOptional = personRepository.findByNameCustomeQuery ("SnailClimb"); assertTrue (personOptional.isPresent ()); assertEquals (Integer.valueOf (23), personOptional.get () .getAge ()) / / find some fields String personName = personRepository.findPersonNameById (id); assertEquals ("SnailClimb", personName); System.out.println (id); / / Update personRepository.updatePersonNameById ("UpdatedName", id); Optional updatedName = personRepository.findByNameCustomeQuery ("UpdatedName"); assertTrue (updatedName.isPresent ()); / / clear database personRepository.deleteAll () }}

Source code address: https://github.com/Snailclimb/springboot-guide/tree/master/source-code/basis/jpa-demo

6. Summary

This article mainly introduces the basic usage of JPA:

Use the method of JPA to add, delete, modify and query as well as condition query.

Customize the SQL statement to query or update the database.

Create an asynchronous method.

In the next article on JPA, I will introduce two very important knowledge points:

Implementation of basic paging function

The realization of paging function under multi-table joint query and multi-table joint query.

Query and pagination of JPA connected tables

For join table queries, it is still very common in JPA, because JPA can customize SQL statements in the respository layer, so it is quite simple to implement join tables by customizing SQL statements. This article is written on the basis of the previous entry to JPA. Those who do not know JPA can read the previous article first.

Based on the previous section, we created two new entity classes, as follows:

1. Creation of related entity classes

Company.java @ Entity @ Data @ NoArgsConstructor public class Company {@ Id @ GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; @ Column (unique = true) private String companyName; private String description; public Company (String name, String description) {this.companyName = name; this.description = description } School.java @ Entity @ Data @ NoArgsConstructor @ AllArgsConstructor public class School {@ Id @ GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; @ Column (unique = true) private String name; private String description;}

two。 Self-defined SQL statement to realize query of connected tables

If we currently want to query Person through the id of the person table, we know that the information of Person is distributed in Company, School and Person, so we need to query with tables if we want to query all the information of Person.

First we need to create a DTO object that contains the Person information we need, and we simply name it UserDTO to save and transfer the information we want.

@ Data @ NoArgsConstructor @ Builder (toBuilder = true) @ AllArgsConstructor public class UserDTO {private String name; private int age; private String companyName; private String schoolName;}

Let's write a method to query out the basic information of Person.

/ * * query with tables * / @ Query (value = "select new github.snailclimb.jpademo.model.dto.UserDTO (p.namejournal p.agereparting c.companyNameparams.name)" + "from Person p left join Company c on p.companyId=c.id" + "left join School son p.schoolId=s.id" + "where p.id=:personId") Optional getUserInformation (@ Param ("personId") Long personId)

You can see that the above sql statement is no different from what we usually write, but the big difference is that there is an operation of a new object.

3. Customize SQL statement to connect table query and realize paging operation

If we want to query all the current personnel information and implement paging, you can do it in the following way. As you can see, in order to achieve paging, we also added the countQuery attribute to the @ Query annotation.

@ Query (value = "select new github.snailclimb.jpademo.model.dto.UserDTO (p.namenarrative p.age.companyNamerecovers.name)" + "from Person p left join Company c on p.companyId=c.id" + "left join School son p.schoolId=s.id" CountQuery = "select count (p.id)" + "from Person p left join Company c on p.companyId=c.id" + "left join School son p.schoolId=s.id") Page getUserInformationList (Pageable pageable)

Actual use:

/ / paging options PageRequest pageRequest = PageRequest.of (0,3, Sort.Direction.DESC, "age"); Page userInformationList = personRepository.getUserInformationList (pageRequest); / / Total query results System.out.println (userInformationList.getTotalElements ()); / / 6 / / by current page size, total number of pages System.out.println (userInformationList.getTotalPages ()); / / 2 System.out.println (userInformationList.getContent ())

4. Extra meals: other uses of customized SQL sentences

I would like to introduce only two of the more commonly used ones:

IN query

BETWEEN query

Of course, there are still many uses that need to be practiced by yourself.

4.1 IN query

In the case where we need to filter out one of several criteria in the sql statement, we can use the IN query, which is also very easy to correspond to the JPA. For example, the following method is implemented to filter the required personnel information by name.

@ Query (value = "select new github.snailclimb.jpademo.model.dto.UserDTO (p.namenarrative p.age.companyNamedros.name)" + "from Person p left join Company c on p.companyId=c.id" + "left join School son p.schoolId=s.id" + "where p.name IN: peopleList") List filterUserInfo (List peopleList)

Actual use:

List personList=new ArrayList (Arrays.asList ("person1", "person2")); List userDTOS = personRepository.filterUserInfo (personList)

4.2 BETWEEN query

The query satisfies a range of values. For example, the following method is used to query the information of people who meet a certain age range.

@ Query (value = "select new github.snailclimb.jpademo.model.dto.UserDTO (p.nameparamagere.companyNamedros.name)" + "from Person p left join Company c on p.companyId=c.id" + "left join School son p.schoolId=s.id" + "where p.age between: small and: big") List filterUserInfoByAge (int small,int big)

Actual use:

List userDTOS = personRepository.filterUserInfoByAge (195.20)

5. Test class and source code address

@ SpringBootTest @ RunWith (SpringRunner.class) public class PersonRepositoryTest2 {@ Autowired private PersonRepository personRepository; @ Sql (scripts = {"classpath:/init.sql"}) @ Test public void find_person_age_older_than_18 () {List personList = personRepository.findByAgeGreaterThan (18); assertEquals (1, personList.size ()) } @ Sql (scripts = {"classpath:/init.sql"}) @ Test public void should_get_user_info () {Optional userInformation = personRepository.getUserInformation (1L); System.out.println (userInformation.get () .toString ()) } @ Sql (scripts = {"classpath:/init.sql"}) @ Test public void should_get_user_info_list () {PageRequest pageRequest = PageRequest.of (0,3, Sort.Direction.DESC, "age"); Page userInformationList = personRepository.getUserInformationList (pageRequest); / / Total query results System.out.println (userInformationList.getTotalElements ()) / / 6 / / according to the current page size, the total number of pages System.out.println (userInformationList.getTotalPages ()); / / 2 System.out.println (userInformationList.getContent ());} @ Sql (scripts = {"classpath:/init.sql"}) @ Test public void should_filter_user_info () {List personList=new ArrayList ("person1", "person2")) List userDTOS = personRepository.filterUserInfo (personList); System.out.println (userDTOS);} @ Sql (scripts = {"classpath:/init.sql"}) @ Test public void should_filter_user_info_by_age () {List userDTOS = personRepository.filterUserInfoByAge (1910); System.out.println (userDTOS) }} this is the end of the article on "how to correctly use JPA in Spring Boot". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report