[JAVA] Spring Boot Introductory Guide I tried [Accessing Data with JPA]

Purpose

For those who have finished working on the Spring Quickstart Guide, those who have started learning Spring Boot, and those who want to review it.

The official is a popular guide, so give it a try! I will share what I learned by actually working on Accessing Data with JPA.

Development environment


OS: macOS Mojave version 10.14.6
Text editor: Visual Studio Code (hereinafter VSCode)
Java: 11.0.2

Click here for a review of the Quickstart Guide Click here for a review of Building a RESTful Web Service Click here for a review of Consuming a RESTful Web Service

1. Start the Spring Boot project!

First, access spring initializr.

  1. Click the ADD DEPENDENCIES button to add Spring Data JPA and H2 Database. スクリーンショット 2020-07-06 13.52.15.png スクリーンショット 2020-07-06 13.52.27.png

** Spring Data JPA (Java Persistence API) is an API for saving and retrieving Java objects in the database (O / R mapping). ** **

** H2 Database toha is a database provided as standard in Java. By adding it here, it is convenient because there is no need to set up a separate server such as MySQL. ** **

2.Artifact, Name changed to ʻaccessing-data-jpa`. 3. Change Java to 11.

Then click the GENERATE button to download the Zip file.

スクリーンショット 2020-07-06 13.55.11.png

Extract the downloaded Zip file and you're ready to go.

2. Add code!

Open the previous folder with VS Code. We recommend installing the Java Extension Pack for extensions. It is said that you should install it. (Only for those who have not installed)

スクリーンショット 2020-06-30 10.08.25.png

Let's create Customer.java!

Create a Customer.java file in src / main / java / com / example / accessingdatajpa /.

スクリーンショット 2020-07-06 14.11.51.png

We will add the code in the Customer.java file.

Customer.java


package com.example.accessingdatajpa;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Customer {

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id;
  private String firstName;
  private String lastName;

  protected Customer() {}

  public Customer(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @Override
  public String toString() {
    return String.format(
        "Customer[id=%d, firstName='%s', lastName='%s']",
        id, firstName, lastName);
  }

  public Long getId() {
    return id;
  }

  public String getFirstName() {
    return firstName;
  }

  public String getLastName() {
    return lastName;
  }
}

We will dig deeper into the code we added to the Customer.java file.

@Entity

Customer.java


@Entity
public class Customer {
  //abridgement
}

The @ Entity annotation is a class associated with the DB table (entity class). Variables defined in this entity class are associated with DB columns.

@ Id,@ GeneratedValue (strategy = GenerationType.AUTO), constructor

Customer.java


@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;

protected Customer() {}

public Customer(String firstName, String lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

In the @Id annotation, the assigned variable becomes the primary key of the table. Also, with the @GeneratedValue (strategy = GenerationType.AUTO) annotation, ids will be automatically generated with serial numbers.

In this Customer table, the primary key is id, and the other columns have firstName and lastName.

As a requirement of the entity class, a constructor with no arguments is required, so define a constructor with no arguments, The constructor with arguments is defined for when creating an instance to be saved in the DB.

③ Definition of toString method and getter method

Customer.java


@Override
public String toString() {
  return String.format(
     "Customer[id=%d, firstName='%s', lastName='%s']",
      id, firstName, lastName);
}

public Long getId() {
  return id;
}

public String getFirstName() {
  return firstName;
}

public String getLastName() {
  return lastName;
}

The toString method is a method that returns a string representation as defined in the java.lang.Object class. The @Override annotation overrides the toString method defined in the ʻObject class with this class. It is an annotation to specify `.

If it is not overridden correctly, an error will occur. Therefore, if you make a typo like toStrign (), an error will occur at compile time and it will tell you.

This time I'm overriding a method that returns a string to display id, firstName, and lastName.

When using the method called String.format, you have to specify the specified format as the first argument, so % s specifies a string and% d specifies a decimal integer and format.

After that, we define a getter method to get each variable.

Let's create CustomerRepository.java!

Create a CustomerRepository.java file in src / main / java / com / example / accessingdatajpa /.

スクリーンショット 2020-07-07 12.01.41.png

We will add code in the CustomerRepository.java file.

CustomerRepository.java


package com.example.accessingdatajpa;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long> {

  List<Customer> findByLastName(String lastName);

  Customer findById(long id);

}

We will dig deeper into the code we added to the CustomerRepository.java file.

① Create a repository interface

CustomerRepository.java


public interface CustomerRepository extends CrudRepository<Customer, Long> {
  //abridgement
}

I am creating an interface called CustomerRepository. At that time, it inherits an interface called CrudRepository. `The CrudRepository interface specifies Customer, which is the type of the entity, and Long, which is the type of the ID, as generic parameters. ``

The CrudRepository interface is an interface that allows you to perform operations such as Create, Read, Update, and Delete (CRUD). Therefore, the Customer Repository interface can also perform the above operations.

② Method implementation

CustomerRepository.java


List<Customer> findByLastName(String lastName);

Customer findById(long id);

In Spring Data JPA, findBy ○○ and methods that satisfy a specific naming convention are defined as ** query methods based on their contents. ** **

This time, findByLastName (String lastName) is applicable. It is a method that can get all the data that matches the lastName received as an argument. findById (long id) is a method that can get the data that matches a specific id.

Let's edit AccessingDataJpaApplication.java!

I think the default state is as follows.

AccessingDataJpaApplication.java


package com.example.accessingdatajpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AccessingDataJpaApplication {
    
    public static void main(String[] args) {
      SpringApplication.run(AccessingDataJpaApplication.class, args);
    }

}

Add the code while referring to the formula.

AccessingDataJpaApplication.java


package com.example.accessingdatajpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

//Added code
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class AccessingDataJpaApplication {

  //Added code
  private static final Logger log = LoggerFactory.getLogger(AccessingDataJpaApplication.class);

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataJpaApplication.class);
  }

  //Added code
  @Bean
  public CommandLineRunner demo(CustomerRepository repository) {
    return (args) -> {
      // save a few customers
      repository.save(new Customer("Jack", "Bauer"));
      repository.save(new Customer("Chloe", "O'Brian"));
      repository.save(new Customer("Kim", "Bauer"));
      repository.save(new Customer("David", "Palmer"));
      repository.save(new Customer("Michelle", "Dessler"));

      // fetch all customers
      log.info("Customers found with findAll():");
      log.info("-------------------------------");
      for (Customer customer : repository.findAll()) {
        log.info(customer.toString());
      }
      log.info("");

      // fetch an individual customer by ID
      Customer customer = repository.findById(1L);
      log.info("Customer found with findById(1L):");
      log.info("--------------------------------");
      log.info(customer.toString());
      log.info("");

      // fetch customers by last name
      log.info("Customer found with findByLastName('Bauer'):");
      log.info("--------------------------------------------");
      repository.findByLastName("Bauer").forEach(bauer -> {
        log.info(bauer.toString());
      });
      // for (Customer bauer : repository.findByLastName("Bauer")) {
      //  log.info(bauer.toString());
      // }
      log.info("");
    };
  }

}

We will dig deeper into the code we added to the AccessingDataJpaApplication.java file.

① log for log output

AccessingDataJpaApplication.java


//Added code
private static final Logger log = LoggerFactory.getLogger(AccessingDataJpaApplication.class);

Logger and LoggerFactory are used to display the log in the terminal. You can get the log by specifying the class in the argument of LoggerFactory.getLogger ().

② Data registration and acquisition

AccessingDataJpaApplication.java


//Added code
@Bean
public CommandLineRunner demo(CustomerRepository repository) {
  return (args) -> {
    // save a few customers
    repository.save(new Customer("Jack", "Bauer"));
    repository.save(new Customer("Chloe", "O'Brian"));
    repository.save(new Customer("Kim", "Bauer"));
    repository.save(new Customer("David", "Palmer"));
    repository.save(new Customer("Michelle", "Dessler"));

    // fetch all customers
    log.info("Customers found with findAll():");
    log.info("-------------------------------");
    for (Customer customer : repository.findAll()) {
      log.info(customer.toString());
    }
    log.info("");

    // fetch an individual customer by ID
    Customer customer = repository.findById(1L);
    log.info("Customer found with findById(1L):");
    log.info("--------------------------------");
    log.info(customer.toString());
    log.info("");

    // fetch customers by last name
    log.info("Customer found with findByLastName('Bauer'):");
    log.info("--------------------------------------------");
    repository.findByLastName("Bauer").forEach(bauer -> {
      log.info(bauer.toString());
    });
    // for (Customer bauer : repository.findByLastName("Bauer")) {
    //  log.info(bauer.toString());
    // }
    log.info("");
  };
}

Registering and acquiring data The method CommandLineRunner demo (CustomerRepository repository) is called by Spring Boot after the app is executed.

First of all, we are registering the data. When instantiating Customer, we are passing a string (firstName, lastName) as an argument to the constructor. Then, the generated Java object is registered in the Customer table by the save method of repository.

python


repository.save(new Customer("Jack", "Bauer"));

Next, I get all the data with findAll (). The extended for statement loops and receives multiple acquired data with the argument customer and outputs them one by one. I am using the overridden toString () when outputting.

python


for (Customer customer : repository.findAll()) {
  log.info(customer.toString());
}

Next, the data with ID 1 is acquired with findById (1L). Since this can only get one specific data, it is output without looping.

python


// fetch an individual customer by ID
Customer customer = repository.findById(1L);
log.info(customer.toString());

Finally, with findByLastName ("Bauer"), we are getting the data with the value of lastName Bauer. Since there can be multiple pieces of this data, it was defined to be received as a List type.

The acquired multiple data are looped by the forEach statement, received by the argument bauer, and output one by one. I think that the commented out extended for statement can be written in this way.

python


// fetch customers by last name
repository.findByLastName("Bauer").forEach(bauer -> {
    log.info(bauer.toString());
});
// for (Customer bauer : repository.findByLastName("Bauer")) {
  //  log.info(bauer.toString());
// }

3. Let's run it!

Now that the application is ready to run, let's check.

Enter the following command in the terminal and press Enter.

Terminal


$ ./mvnw spring-boot:run

After a while, the following characters will appear in the terminal.

Terminal


Customers found with findAll():
-------------------------------
Customer[id=1, firstName='Jack', lastName='Bauer']
Customer[id=2, firstName='Chloe', lastName='O'Brian']
Customer[id=3, firstName='Kim', lastName='Bauer']
Customer[id=4, firstName='David', lastName='Palmer']
Customer[id=5, firstName='Michelle', lastName='Dessler']

Customer found with findById(1L):
--------------------------------
Customer[id=1, firstName='Jack', lastName='Bauer']

Customer found with findByLastName('Bauer'):
--------------------------------------------
Customer[id=1, firstName='Jack', lastName='Bauer']
Customer[id=3, firstName='Kim', lastName='Bauer']

Reference site

** As the basis of JPA related annotation-Part 1- ** ** Entity Class Requirements ** CrudRepository ** [Spring Data JPA] Automatically implemented method naming rule **

Recommended Posts

Spring Boot Introductory Guide I tried [Accessing Data with JPA]
I tried to get started with Spring Data JPA
I tried GraphQL with Spring Boot
I tried Flyway with Spring Boot
I tried Lazy Initialization with Spring Boot 2.2.0
I tried Spring Boot introductory guide [Building a RESTful Web Service]
Spring Boot Introductory Guide I tried [Consuming a RESTful Web Service]
I tried to get started with Swagger using Spring Boot
See the behavior of entity update with Spring Boot + Spring Data JPA
OR search with Spring Data Jpa Specification
I tried Spring Data JDBC 1.0.0.BUILD-SNAPSHOT (-> 1.0.0.RELEASE)
I tried Spring.
Implementation method for multi-data source with Spring boot (Mybatis and Spring Data JPA)
I wanted to gradle spring boot with multi-project
Sort by Spring Data JPA (with compound key sort)
Creating a common repository with Spring Data JPA
Spring Boot + Spring Data JPA About multiple table joins
I tried to clone a web application full of bugs with Spring Boot
[I tried] Spring tutorial
I tried Spring Batch
Download with Spring Boot
I tried to implement file upload with Spring MVC
05. I tried to stub the source of Spring Boot
I tried to reduce the capacity of Spring Boot
I wrote a test with Spring Boot + JUnit 5 now
Hello World with Spring Boot
Implement GraphQL with Spring Boot
I tried DI with Ruby
Get started with Spring boot
Implement REST API with Spring Boot and JPA (Application Layer)
Implement REST API with Spring Boot and JPA (Infrastructure layer)
[spring] Let's use Spring Data JPA
Hello World with Spring Boot!
Run LIFF with Spring Boot
SNS login with Spring Boot
I tried Spring State machine
File upload with Spring Boot
Spring Boot starting with copy
Connect to database with spring boot + spring jpa and CRUD operation
Spring Boot starting with Docker
Flow until output table data to view with Spring Boot
Hello World with Spring Boot
Set cookies with Spring Boot
Use Spring JDBC with Spring Boot
I tried UPSERT with PostgreSQL.
Add module with Spring Boot
Getting Started with Spring Boot
Implement REST API with Spring Boot and JPA (domain layer)
I tried BIND with Docker
Create microservices with Spring Boot
Send email with spring boot
I tried printing a form with Spring MVC and JasperReports 1/3 (JasperReports settings)
I tried printing a form with Spring MVC and JasperReports 3/3 (Spring MVC control)
I implemented an OAuth client with Spring Boot / Security (LINE login)
I tried connecting to MySQL using JDBC Template with Spring MVC
Dynamically generate queries with Spring Data JPA (multi-word search) (paging support)
I made a simple search form with Spring Boot + GitHub Search API.
Creating REST APIs with Spring JPA Data with REST and Lombok incredibly easy.
Use Basic Authentication with Spring Boot
gRPC on Spring Boot with grpc-spring-boot-starter
Create an app with Spring Boot 2