添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
失眠的桔子  ·  GdiPlus[24]: ...·  6 月前    · 
低调的风衣  ·  比亚迪宋plus ...·  1 年前    · 
This is the day! At last! You've finally arrived where the real adventure begins. In this chapter, you will add the Spring Data JPA to your project and start writing data to the database using Spring and Hibernate. Admit it, you've been waiting for this moment in the course :) Today you will learn the basic concepts of binding Java code to a database. You will learn what JPA entities and Spring Data JPA repositories are. You will also learn how to use ready-made repository methods in your SportEventService class. It promises to be interesting. Isn't it?

Configuration first

After reading chapters Maven Starter Maven pom & Spring Boot you probably remember that the pom.xml file is the configuration file for projects based on the Apache Maven tool. It defines dependencies, versions, properties and many other aspects of the project. So if you want to add a new technical solution to your project, such as database support, you need to add new dependencies to pom.xml .

H2 Database Engine

H2 is a lightweight, fast and open source SQL database written in Java. This dependency allows you to use the H2 database in your project. H2 is often used as an in-memory database for testing or as a local development environment. Such a database is also a great solution at the beginning of the learning curve, as it does not require the installation of any additional tools or external services (such as a database server). The data is only kept during a particular run of your project, so each time you restart Spring Boot, your database will be empty. This is fine. You don't need anything else at this stage.

Spring Boot Starter Data JPA

Another dependency defines the Spring Boot starter for the Spring Data JPA . Spring Data JPA is a Spring Data module that facilitates the creation of a data access layer ( DAO ) for Java applications based on Java Persistence API ( JPA ) technology. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> JPA is an object-relational mapping (ORM) standard that allows Java objects to be mapped to records in a database. This standard is most commonly implemented by Hibernate. In other words, Spring Data JPA is a layer on top of Spring that simplifies the use of the database. JPA provides a set of interfaces with specific methods. It does not worry about implementation. The implementation is provided by Hibernate's libraries, which are pulled into your project when you plug JPA into your project. It is Hibernate that actually implements the writing/reading to and from the database (and all other database operations). From the point of view of your project's code, Hibernate itself is not that important to you. You are more interested in the aforementioned JPA interfaces, which in Spring Boot 3 can be found in the jakarta libraries (in Spring Boot 2 and before it was javax.persistence ): This Starter provides the dependencies needed to use input validation in a Spring Boot project. It introduces support for validating objects using annotations as defined in JSR-303/JSR-380 (Java Specification Requests) and an implementation of these specifications - Bean Validation 2.0 (Hibernate Validator). If you do not include this dependency, you will get an error when building the project: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found . Add a provider like Hibernate Validator (RI) to your classpath. at jakarta.validation.Validation$GenericBootstrapImpl.configure(Validation.java:291) ~[jakarta.validation-api-3.0.2.jar:na] at jakarta.validation.Validation.buildDefaultValidatorFactory(Validation.java:103) ~[jakarta.validation-api-3.0.2.jar:na] It is worth remembering this solution as it is common for projects using Spring Boot 2 to encounter this error when upgrading to version > 2.3.x or Spring Boot 3. If you encounter such a problem in your project in the future, or someone else asks about it on a forum, you will have a solution ready. Once you have linked the dependencies to your project, you need to rebuild it.

Use mvn clean install to do this, as you learned in the First Maven build in the Building a project with Maven section. Remember to reload your project into IntelliJ after you have built it. You can now proceed to update the code so that it no longer stores the data in the map.
It will now store it in the database.

Create entity

You now want to use the new dependencies to store your SportEvent in the database. To do this, you will need to add some code to the SportEvent class. This will mainly be JPA annotations derived from jakarta.persistence . The @Entity , @Table annotations are annotations that describe the class. While @Id , @SequenceGenerator and @GeneratedValue describe a field with a unique key ( PRIMARY KEY in the database). @SequenceGenerator (name = "SportingEventsSequence", sequenceName = "sporting_events_seq", allocationSize = 1) @GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "SportingEventsSequence") private final Long id; private String name; A Java class now represents a database entity using the Java Persistence API ( JPA ) library. JPA is a standard that provides object-relational mapping ( ORM ) for Java applications. Your class now represents the sport_events table from the database in your code.

Here is an explanation of each annotation: @Entity — annotation indicating that the SportEvent class is an entity and will be mapped to a table in the database @Table (name = "sport_events" ) — annotation indicating that the entity should be mapped to a table named sport_events in the database @Id — annotation indicating that the id field is the PRIMARY KEY in the table. @SequenceGenerator (name = "SportingEventsSequence" , sequenceName = "sporting_events_seq" , allocationSize = 1) — annotation that defines a sequence generator used to generate unique values for the primary key. The generator is named SportingEventsSequence and the sequence in the database is named sporting_events_seq . Next attribute allocationSize is set to 1 , meaning that the sequence is incremented by 1 for each new entity. @GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "SportingEventsSequence" ) — annotation indicating that the id value should be automatically generated using a predefined sequence generator named SportingEventsSequence (note that the generator name must match the name given in the @SequenceGenerator annotation, i.e. SportingEventsSequence ). Now that you have a JPA entity , you need to exploit the potential of the Spring Data JPA . So you will create a repository interface that will be responsible for handling the entity, i.e. writing and reading it into the database and any other database operations. Note. A repository is a programming design pattern that allows the abstraction of a data access layer (DAO - Data Access Object) in an application. A repository allows data to be stored, retrieved, modified and deleted in a way that is independent of the details of a particular data storage technology, such as a database, file or API. In the context of the Spring Data JPA , a repository is a Java interface that extends one of the Spring Data interfaces (e.g. JpaRepository or CrudRepository ). Spring Data automatically generates implementations of these interfaces, providing out-of-the-box methods for basic data operations such as saving, updating, deleting, or finding entities. In addition, the repository can contain custom methods generated based on method names or @Query annotations. Przykładowe metody, które znajdziesz w JpaRepository or interfaces from which it inherits: <S extends T> List<S> saveAll(Iterable<S> entities); List<T> findAll(); List<T> findAllById(Iterable<ID> ids); Even with these few methods, you probably have a better understanding of why we need repository interfaces. They provide specific methods for writing and reading data passed in an entity. Note. In Spring Boot, you do not need to add the @Repository annotation to a repository interface if it extends one of the core Spring Data interfaces, such as JpaRepository or CrudRepository . In this case, Spring Boot automatically detects these interfaces as repositories and manages them as Spring components.

@Repository public interface SportEventRepository extends JpaRepository<SportEvent, Long> { In Spring Boot, you don't have to do this and, in any case, your repository object becomes a bean and you can inject it into your service.

Redevelop your service

Now it's time to get rid of the map in the service and use the database for writing. We will use the in-memory H2 database for this. The database will be empty after each start of the application, so you can restart the project as many times as you like to get the same data state each time (i.e. de facto no data in the database).

For ease of learning, we will keep the current version of the service for comparison. We will change the name from SportEventService to SportEventServiceOld and add the @Deprecated annotation to indicate that the class is deprecated and ready for removal. This is a standard practice in Java for marking code elements that become redundant over time and are destined for removal in the future. private AtomicLong index = new AtomicLong(3); private final Map<Long, SportEvent> events = new HashMap<>(); events.put(1L, new SportEvent(1L, "Volleyball match")); events.put(2L, new SportEvent(2L, "Football match")); events.put(3L, new SportEvent(3L, "Boxing fight")); public List<SportEventResponse> getAll() { return events.values().stream() .map(sportEvent -> new SportEventResponse(sportEvent.getId(), sportEvent.getName())) .toList(); So you will not find a map in the new SportEventService . Instead, you need to inject your repository there. So you add a new field and use the @RequiredArgsConstructor annotation to annotation to create a constructor that injects the repository into the service (i.e. just like the service is injected into the API class). Thus you have such a sequence of calls when handling a request: The api method calls the service method and this calls the repository method which writes/reads the data in the database. In other words, in the methods, instead of using the map, you use the appropriate repository methods, e.g. findAll . @RequiredArgsConstructor @Slf4j @Service public class SportEventService { private final SportEventRepository sportEventRepository; public List<SportEventResponse> getAll() { return sportEventRepository. findAll() .stream() .map(sportEvent -> new SportEventResponse(sportEvent.getId(), sportEvent.getName())) .collect(Collectors.toList()); You are now using a database! The data in the database is volatile, as it is only held in memory during a given project start-up, but this is fully sufficient at this stage.

Configure database

To test the new solution, all you need to do is send a request from Swagger to create a new sporting event after launching the project and then retrieve all the events using the data retrieval endpoint.

If you want to access the database to view data directly in it, you still need to add its configuration to the configuration file for the Spring Boot project. This file is application.properties. You add such elements there: spring.datasource.url=jdbc:h2:mem:testdb;DATABASE_TO_UPPER=false spring.h2.console.enabled=true spring.h2.console.path=/console
  • jdbc:h2:mem:testdb — a JDBC URL that indicates that an H2 database in memory mode called testdb is in use
  • DATABASE_TO_UPPER=false — an additional parameter that specifies that table and column names will not be automatically converted to uppercase. In H2, names are converted to uppercase by default, but setting this parameter to false preserves the original case
  • spring.h2.console.enabled=true — enables the built-in H2 console, which allows access to the database via a web browser spring.h2.console.path=/console — specifies the URL path where the H2 console will be available. In this case it will be http://localhost:port/console , where port is the port on which the application is running (default: 8080 ) In summary, this configuration sets the H2 database in memory mode with the name testdb , enables the built-in H2 console and makes it available under the /console path.

    Browse database

    When you start a project, your base is empty. However, you can go into Swagger and save a new event using the sports event creation endpoint you already know. Since you already have access to the database, take advantage of this and check what the data of the saved event looks like in the database. According to your configuration from the application.properties file, type into your browser: That's all for today. You've done a good job today, but a lot of knowledge to be gained still lies ahead! You will soon learn how to connect a real database, such as Postgres, to the project. You can get spring-boot-3-web project from our new github — javappa-coding/coding-lab/tags
    This is a tag created after chapter 33.

    Code version applicable from chapter 34 — javappa-coding/coding-lab Possibility to ask questions to people creating a community built around the same interests Direct contact with the course author! Exchange of experiences between group members Friendly atmosphere We're constantly evolving, so stay tuned! We will send information about major updates to this address, as well as about new materials appearing on the site. Javappa is also professional programming services based on JAVA technologies. If you want to contact us for advice or to create a web application, you should learn about our experience. Click About Us. Click About us
    Website positioning: TENSE Group