About Spring Data
A top project in the Spring community is mainly used to simplify data (relational & non-relational) access. If we use Spring Data to develop programs, we can save a lot of low-level data access operations, such as writing data query statements, DAO classes, etc. We only need to write some abstract interfaces and define related operations. Spring will create proxy instances during operation to implement the operations defined in our interface.
About Spring Data Subproject
Spring Data has many sub-projects, in addition to Spring Data Jpa, there are also the following sub-projects.
Spring Data Commons
Spring Data MongoDB
Spring Data Redis
Spring Data Solr
Spring Data Gemfire
Spring Data REST
Spring Data Neo4j
About Spring Data Jpa
Spring Data Jpa is a sub-project of Spring Data. It is mainly used to simplify the implementation of the data access layer. Using Spring Data Jpa, you can easily implement addition, deletion, modification, pagination, sorting, etc.
Example, Spring Boot + Spring Data Jpa
1. Add POM.XML file
As shown below:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-data-jpa-example</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.4.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.7</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> </dependencies> <build> <plugins> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
Among them, spring-boot-starter-parent will load all the default configurations required by Spring Boot application;
spring-boot-starter-data-jpa will download all the dependencies required by Spring Data Jpa;
Add spring-boot-starter-web because our project is a web application;
In addition, our database is mysql, so mysql-connector-java dependency is also required;
Since cache is used, add another spring-boot-starter-cache dependency;
2. Write entity User
package com.example.domain;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.NamedQuery;@Entity@NamedQuery(name = "User.findByName", query = "select name,address from User u where u.name=?1")public class User implements Serializable{ private static final long serialVersionUID = 1L; @Id long id; @Column(name = "name") String name; @Column(name = "address") String address; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; }}There is nothing else to say. Pay attention to the @NamedQuery annotation here. It roughly means that the findByName method we define in the Repository interface does not use the default query implementation, but instead uses this custom query statement to query. If there is no annotation here, the default implementation will be used.
3. Write the Repository interface
Here we will write two Repository interfaces, which are only used for examples, and can be merged into one in practice:
UserJpaRepository
package com.example.repository;import org.springframework.data.jpa.repository.JpaRepository;import com.example.domain.User;public interface UserJpaRepository extends JpaRepository<User,Long> {}The UserJpaRepository interface here implements the JpaRepository interface;
In fact, JpaRepository implements the PagingAndSortingRepository interface, the PagingAndSortingRepository interface implements the CrudRepository interface, and the CrudRepository interface implements the Repository interface;
A brief explanation:
The Repository interface is an identification interface, and it is empty inside;
The CrudRepository interface defines the methods of adding, deleting, modifying and searching;
The PagingAndSortingRepository interface is used for paging and sorting;
Since the JpaRepository interface inherits all of the above interfaces, it has all the methods declared by them;
Also note that taking the findAll method as an example, the JpaRepository interface returns List, PagingAndSortingRepository and CrudRepository return iterator;
UserRepository
package com.example.repository;import java.util.List;import org.springframework.data.jpa.repository.Query;import org.springframework.data.repository.Repository;import org.springframework.data.repository.query.Param;import com.example.domain.User;public interface UserRepository extends Repository<User, Long>{ List<User> findByNameAndAddress(String name, String address); @Query(value = "from User u where u.name=:name") List<User> findByName1(@Param("name") String name); @Query(value = "select * from #{#entityName} u where u.name=?1", nativeQuery = true) List<User> findByName2(String name); List<User> findByName(String name);}The UserRepository interface here mainly defines some query methods;
For example, we can execute directly without defining other query statements here. Spring Data Jpa will automatically implement the method based on the attribute name and method name of the entity class; PS: Since we declare the @NamedQuery annotation in the entity class, in fact, the findByName method will use the query statement annotated by the @NamedQuery annotation to query;
In addition, the findByName1 method here uses HQL statement query;
The findByName2 method uses the original SQL statement query;
4. Write Service
Service interface:
package com.example.service;import java.util.List;import com.example.domain.User;public interface IUserService{ public List<User> findAll(); public void saveUser(User book); public User findOne(long id); public void delete(long id); public List<User> findByName(String name);}Interface implementation class:
package com.example.service.impl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.example.domain.User;import com.example.repository.UserRepository;import com.example.repository.UserJpaRepository;import com.example.service.IUserService;@Service@Transactionalpublic class UserServiceImpl implements IUserService{ @Autowired private UserJpaRepository userJpaRepository; @Autowired private UserRepository userRepository; public List<User> findAll() { return userJpaRepository.findAll(); } public List<User> findByName(String name) { List<User> userList1 = userRepository.findByName1(name); List<User> userList2 = userRepository.findByName2(name); List<User> userList3 = userRepository.findByNameAndAddress(name, "3"); System.out.println("userList1:" + userList1); System.out.println("userList2:" + userList2); System.out.println("userList3:" + userList3); return userRepository.findByName(name); } public void saveUser(User book) { userJpaRepository.save(book); } @Cacheable("users") public User findOne(long id) { System.out.println("Cached Pages"); return userJpaRepository.findOne(id); } public void delete(long id) { userJpaRepository.delete(id); }}There is nothing to say about this, just call the Repository interface method.
5. Write Controller
There is nothing to say about Controller, just call Service. Note that the Controller here is annotated using the @RestController annotation, and the URL path name is named according to the RESTful style;
package com.example.web;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.example.domain.User;import com.example.service.IUserService;@RestController@RequestMapping(value = "/users")public class UserController{ @Autowired private IUserService userService; @RequestMapping(value = "/add/{id}/{name}/{address}") public User addUser(@PathVariable int id, @PathVariable String name, @PathVariable String address) { User user = new User(); user.setId(id); user.setName(name); user.setAddress(address); userService.saveUser(user); return user; } @RequestMapping(value = "/delete/{id}") public void deleteBook(@PathVariable int id) { userService.delete(id); } @RequestMapping(value = "/") public List<User> getBooks() { return userService.findAll(); } @RequestMapping(value = "/{id}") public User getUser(@PathVariable int id) { User user = userService.findOne(id); return user; } @RequestMapping(value = "/search/name/{name}") public List<User> getBookByName(@PathVariable String name) { List<User> users = userService.findByName(name); return users; }}6. Configure datasource
Add the following configuration to the application.properties file:
spring.jpa.show-sql = truelogging.level.org.springframework.data=DEBUGspring.jpa.hibernate.ddl-auto=spring.datasource.url=jdbc:mysql://localhost:3306/demospring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.jdbc.Driver
If you use STS IDE, these attribute configurations will be automatically prompted, so you can save searches.
If you want to view the configuration of spring.datasource, you can refer to this class: DataSourceProperties.java
7. Write a startup class
It is relatively simple. Note that the package level to which this class belongs should be greater than or equal to other classes to ensure that the annotations of other classes can be scanned.
package com.example;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication@EnableCachingpublic class SpringDataJpaExampleApplication { public static void main(String[] args) { SpringApplication.run(SpringDataJpaExampleApplication.class, args); }}Run and test the program
Start the main method, or type it into a jar package to run;
Enter the following URL in the browser and test it:
http://localhost:8080/users/
http://localhost:8080/users/add/100/110/111
http://localhost:8080/users/delete/100
http://localhost:8080/users/2
http://localhost:8080/users/search/name/2
Program source code
https://github.com/peterchenhdu/spring-data-jpa-example
References
http://docs.spring.io/spring-data/jpa/docs/1.11.0.RELEASE/reference/html/
http://javabeat.net/spring-data-jpa/
https://spring.io/guides/gs/caching/
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.