Spring Data Jpa是Spring数据家族的一部分。Spring Data使创建Spring驱动的应用程序变得更加容易,这些应用程序使用新的方法访问数据,例如非关系数据库、地图简化框架、云服务以及高级关系数据库支持。本文将讨论Spring Data Jpa。我们还将研究Spring Data Jpa示例应用程序。
目录
Spring数据JPA
Spring Data JPA提供的一些很酷的特性包括:
- 创建并支持使用Spring和JPA创建的存储库
- 支持QueryDSL和JPA查询
- 域类审核
- 支持批量加载、排序、动态查询
- 支持实体的XML映射
- 使用CrudRepository减少通用CRUD操作的代码大小
何时使用Spring数据JPA?
如果您需要快速创建一个主要用于CRUD操作的基于JPA的存储库层,而您不想创建抽象的刀,实施接口,Spring Data Jpa是一个不错的选择。
Spring数据JPA示例
对于Spring Data Jpa示例,我们将创建一个RESTful web服务将连接到Postgresql数据库。我们将实现基本的CRUD操作并处理我们已经创建的示例数据。
springjap示例数据
使用下面的查询在Postgresql数据库中创建表并添加一些测试数据。
create table people (
id serial not null primary key,
first_name varchar(20) not null,
last_name varchar(20) not null,
age integer not null
);
insert into people (id, first_name, last_name, age) values
(1, "Vlad", "Boyarskiy", 21),
(2,"Oksi", " Bahatskaya", 30),
(3,"Vadim", " Vadimich", 32);
Spring Data Jpamaven项目结构
下图显示了最终的springjpa项目结构。稍后我们将详细研究每个组件。
Spring Data Jpamaven依赖项
我们需要为Spring Data Jpa示例项目添加以下依赖项。
postgresql
: Postgresql java driver.spring-core
,spring-context
: Spring框架核心依赖项。spring-webmvc
,jackson-databind
: For Spring座应用程序。spring-data-jpa
,hibernate-entitymanager
: for Spring Data JPA and Hibernate支持。
以下是期末考试的内容pom.xml文件生成文件。
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev</groupId>
<artifactId>springData</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Spring Data JPA Maven Webapp</name>
<url>https://maven.apache.org</url>
<properties>
<spring.framework>4.3.0.RELEASE</spring.framework>
<postgres.version>42.1.4</postgres.version>
<serializer.version>2.8.1</serializer.version>
<spring.data>1.3.4.RELEASE</spring.data>
<hibernate.manager>4.2.5.Final</hibernate.manager>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.framework}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.framework}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring.data}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.manager}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${serializer.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
Spring配置类
package com.journaldev.spring.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.ejb.HibernatePersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("com.journaldev.spring.repository")
@PropertySource("classpath:database.properties")
public class DataConfig {
private final String PROPERTY_DRIVER = "driver";
private final String PROPERTY_URL = "url";
private final String PROPERTY_USERNAME = "user";
private final String PROPERTY_PASSWORD = "password";
private final String PROPERTY_SHOW_SQL = "hibernate.show_sql";
private final String PROPERTY_DIALECT = "hibernate.dialect";
@Autowired
Environment environment;
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lfb = new LocalContainerEntityManagerFactoryBean();
lfb.setDataSource(dataSource());
lfb.setPersistenceProviderClass(HibernatePersistence.class);
lfb.setPackagesToScan("com.journaldev.spring.model");
lfb.setJpaProperties(hibernateProps());
return lfb;
}
@Bean
DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUrl(environment.getProperty(PROPERTY_URL));
ds.setUsername(environment.getProperty(PROPERTY_USERNAME));
ds.setPassword(environment.getProperty(PROPERTY_PASSWORD));
ds.setDriverClassName(environment.getProperty(PROPERTY_DRIVER));
return ds;
}
Properties hibernateProps() {
Properties properties = new Properties();
properties.setProperty(PROPERTY_DIALECT, environment.getProperty(PROPERTY_DIALECT));
properties.setProperty(PROPERTY_SHOW_SQL, environment.getProperty(PROPERTY_SHOW_SQL));
return properties;
}
@Bean
JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
@Configuration
: this 春注说它是配置类。@EnableTransactionManagement
: this annotation allows users to use transaction management in application.@EnableJpaRepositories("com.journaldev.spring.repository")
: indicates where the repositories classes are present.@PropertySource("classpath:database.properties")
: says that we have property file in our classpath. The values from this file will be injected into environment variable. The contents of the database.properties file are shown below.driver=org.postgresql.Driver url=jdbc:postgresql://127.0.0.1:5432/postgres user=postgres password=postgres hibernate.dialect=org.hibernate.dialect.PostgreSQL82Dialect hibernate.show_sql=true
- 对于使用Spring数据,首先我们必须配置
DataSource
bean. Then we need to configureLocalContainerEntityManagerFactoryBean
bean. We need this bean to control the entities. In this beans, you must specify the persistence provider i.e.HibernatePersistence
in our case. - 下一步是为配置bean交易管理. 在我们的例子中
JpaTransactionManager
. Note that without configuring transaction manager we can’t use@Transactional
注解.
AppInitializer
and WebConfig
classes are to configure our application as web application without using web.xml file.
模型类
package com.journaldev.spring.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "people")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "age")
private Integer age;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
public Person() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "Person{" + "id=" + id + ", age=" + age + ", firstName="" + firstName + """ + ", lastName="" + lastName
+ """ + "}";
}
}
这里我们有一些新的注解。让我们更详细地讨论一下。
- @Entity:这个注解允许实体管理器使用这个类并把它放到上下文中。
- @Table(name=“;people”;):将类与数据库中的表相关联。
@Id
: says that this field is the primary key.@GeneratedValue(strategy = GenerationType.IDENTITY)
: Defines the strategy for generating the primary key.@Column(name = "age")
: denotes a column in the database with which this field will be associated.
Spring数据JPA存储库
下一步是创建存储库。
package com.journaldev.spring.repository;
import org.springframework.data.repository.CrudRepository;
import com.journaldev.spring.model.Person;
import java.util.List;
public interface PersonRepository<P> extends CrudRepository<Person, Long> {
List<Person> findByFirstName(String firstName);
}
通过继承CrudRepository
, we can call many methods without the need to implement them ourself. Some of these methods are:
- 节约
- 芬顿
- 存在
- 芬德尔
- 计数
- 删除
- 全部删除
我们也可以定义自己的方法。这些方法名应使用特殊关键字,如“;find”;,“;order”。Spring Data Jpa开发人员已经尝试考虑您可能需要的大多数可能的选项。在我们的例子中findByFirstName(String firstName)
method returns all entries from table where field first_name
equals to firstName
.
这是Spring Data Jpa最重要的特性之一,因为它减少了大量的锅炉板代码。此外,由于这些Spring方法已经被许多已经在使用它们的项目测试得很好,所以出错的可能性也较小。
Spring服务班
现在我们的Spring Data Jpa代码已经准备好了,下一步是创建服务类并定义我们将必须使用数据库表的方法。
package com.journaldev.spring.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.journaldev.spring.model.Person;
import com.journaldev.spring.repository.PersonRepository;
@Service
public class PersonService {
@Autowired
PersonRepository<Person> personRepository;
@Transactional
public List<Person> getAllPersons() {
return (List<Person>) personRepository.findAll();
}
@Transactional
public List<Person> findByName(String name) {
return personRepository.findByFirstName(name);
}
@Transactional
public Person getById(Long id) {
return personRepository.findOne(id);
}
@Transactional
public void deletePerson(Long personId) {
personRepository.delete(personId);
}
@Transactional
public boolean addPerson(Person person) {
return personRepository.save(person) != null;
}
@Transactional
public boolean updatePerson(Person person) {
return personRepository.save(person) != null;
}
}
@Transactional
annotation indicates that the method will be executed in the transaction. Spring will take care of transaction management.
Spring控制器类
最后一步是创建控制器类,将我们的API公开给外部世界。
package com.journaldev.spring.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.journaldev.spring.model.Person;
import com.journaldev.spring.services.PersonService;
@RestController
public class PersonController {
@Autowired
PersonService personService;
@RequestMapping(value = "/person/{id}", method = RequestMethod.GET)
public @ResponseBody Person getAllUsers(@PathVariable Long id) {
return personService.getById(id);
}
@RequestMapping(value = "/personByName/{name}", method = RequestMethod.GET)
public List<Person> getPersoneByName(@PathVariable String name) {
return personService.findByName(name);
}
@RequestMapping(value = "/person", method = RequestMethod.GET)
public List<Person> getAll() {
return personService.getAllPersons();
}
@RequestMapping(value = "/person/{id}", method = RequestMethod.DELETE)
public HttpStatus deletePersnone(@PathVariable Long id) {
personService.deletePerson(id);
return HttpStatus.NO_CONTENT;
}
@RequestMapping(value = "/person", method = RequestMethod.POST)
public HttpStatus insertPersone(@RequestBody Person person) {
return personService.addPerson(person) ? HttpStatus.CREATED : HttpStatus.BAD_REQUEST;
}
@RequestMapping(value = "/person", method = RequestMethod.PUT)
public HttpStatus updatePerson(@RequestBody Person person) {
return personService.updatePerson(person) ? HttpStatus.ACCEPTED : HttpStatus.BAD_REQUEST;
}
}
Spring数据JPA测试
只需构建项目并将其部署到您最喜欢的servlet容器(如Tomcat)中。下图显示了一些API调用的响应。
Spring数据JPA Read All
Spring数据JPA按名称获取
Spring数据JPA创建
Spring数据JPA更新
Spring数据JPA删除
以上是Spring Data Jpa示例教程。你可以从下面的链接下载最终的项目。
参考文献:官方网站