This article briefly describes the use of Spring Data JPA to store and retrieve data in relational databases.
What applications will you create?
You will create an access to Customer in the memory database POJOs Application.
Dead work:
- About 15 minutes
- Your favorite text editor or IDE
- JDK >= 1.8
- Maven >= 3.0
Create directory structure
Under the project directory of your choice, create the following directory structure; for example, use mkdir-p src/main/java/hello on the * nix system:
└── src └── main └── java └── hello
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> <artifactId>gs-accessing-data-jpa</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-releases</id> <name>Spring Releases</name> <url>https://repo.spring.io/libs-release</url> </repository> <repository> <id>org.jboss.repository.releases</id> <name>JBoss Maven Release Repository</name> <url>https://repository.jboss.org/nexus/content/repositories/releases</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-releases</id> <name>Spring Releases</name> <url>https://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project>
Define a simple entity
In this example, a new Customer object is created by annotating JPA entities.
src/main/java/hello/Customer.java
package hello; 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); } }
The Customer class has three attributes, id, firstName, and lastName. The class has two constructors. JPA needs a default constructor. You don't need to use it directly, so it's set to protected. The other constructor is just for the convenience of creating Customer instances and storing them in the database.
> In this article, getters and setters methods are omitted for brevity.
The Customer class is annotated with @Entity to indicate that it is a JPA entity. Because there is no @Table annotation, the tables mapped in the database are named entities Customer.
>@ When annotating the Entity class, the table name after the database mapping is entity name, and the field name and attribute name are the same.
>@ When you comment on a Table class, the default is the same as @Entity, but you can specify the table name with @Table(name='value') and the field name with @Column(name='value').
Customer's ID attribute is recognized by JPA annotated with @Id, and it is also annotated with @GeneratedValue as the ID.id attribute of the object, indicating that the ID will increase automatically.
First Name and lastName attributes are not annotated. They will be mapped to fields with the same attribute name.
toString() can easily output the attributes of customer
Create simple queries
Spring Data JPA uses JPA to store data in relational databases. Its greatest feature is that it inherits the repository interface and can automatically create query methods for you at run time.
Create Customer's repository interface:
src/main/java/hello/CustomerRepository.java
package hello; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface CustomerRepository extends CrudRepository<Customer, Long> { List<Customer> findByLastName(String lastName); }
Customer Repository inherits CrudRepository interface. CrudRepository has two specified parameter entity types and ID types. Here we pass Customer and Long. Customer Repository through CrudRepository inheritance have several methods of Customer persistence, including basic add-delete checks.
Spring Data JPA also allows you to define some other query methods by yourself, just through some simple naming rules. findByLastName() in Customer Repository is such a method.
In general Java applications, you write a class to implement CustomerRepository. But Spring Data JPA is so powerful: you don't need to write the implementation of the repository interface. Spring Data JPA will help you create the application automatically during the running process.
Create an application
src/main/java/hello/Application.java
package hello; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class Application { private static final Logger log = LoggerFactory.getLogger(Application.class); public static void main(String[] args) { SpringApplication.run(Application.class); } @Bean public CommandLineRunner demo(CustomerRepository repository) { return (args) -> { // save a couple of 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.findOne(1L); log.info("Customer found with findOne(1L):"); log.info("--------------------------------"); log.info(customer.toString()); log.info(""); // fetch customers by last name log.info("Customer found with findByLastName('Bauer'):"); log.info("--------------------------------------------"); for (Customer bauer : repository.findByLastName("Bauer")) { log.info(bauer.toString()); } log.info(""); }; } }
@ SpringBoot Application is a "composite" annotation that contains the following annotations:
- @ Configuration annotations use classes as sources of program context bean s.
- @ Enable AutoConfiguration tells Spring Boot to add beans and lots of other settings when it starts.
- You need to add @Enable WebMvc as a Spring MVC application, but Spring Boot will automatically add. This annotation indicates that the application is a web application and deactivates settings like Dispatcher Servlet.
-
@ ComponentScan tells Spring to find other components, configure and service in the hello package, and allow the discovery of controllers.
The main() method uses the Spring Boot's Spring Application. run () method to start the application. I wonder if you noticed that we don't have an XML file? Not even a web.xml file. This web application is 100% pure Java and you don't have to deal with any basic configuration.
There are several Customer Repository tests in the main() method. First, get Customer Repository from the Spirng application context. Then save() method is used to save several Customer objects. Then, use findAll() method to get all Customer objects from the database. Similarly, you can use findOne() to get a Customer object through id. Finally, you can use findByLastName() side. The method uses "Bauer" to find the Customer object.
> The default SpringBook JPA repository supports scanning in the package and its subpackages where @SpringBoot Application resides. If the location of the JPA repository interface is not obvious, you can use the @Enable Jpa Repositories annotation and pass the basePackageClasses=MyRepository.class parameter to indicate the location.
Compile to JAR file
You can compile your application into JAR files that contain dependencies, classes, and resources. JAR files are more convenient to deploy in different running environments.
You can run the application using the. / mvnw spring-boot:run command. Or compile it into a JAR file using. / mvnw clean package command. Then you can run the JAR file:
java -jar target/gs-accessing-data-jpa-0.1.0.jar
> This command will create a runnable JAR file, and of course you can compile it into a WAR file.
You will see the following:
== 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 findOne(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']
summary
Congratulations! You've learned a simple way to use Spring Data JPA to store an object into a database and get it through the repository interface.