Spring Data JPA

Spring Data JPA is part of Spring Data family. Spring Data makes it easier to create Spring driven applications that use new ways to access data, such as non-relational databases, map-reduction frameworks, cloud services, as well as well-advanced relational database support. This article will discuss about Spring Data JPA. We will also look into Spring Data JPA example application.

Spring Data JPA是Spring Data系列的一部分。 Spring Data使使用新方法访问数据的Spring驱动的应用程序变得更容易,例如非关系数据库,地图缩减框架,云服务以及先进的关系数据库支持。 本文将讨论Spring Data JPA。 我们还将研究Spring Data JPA示例应用程序。

Spring Data JPA (Spring Data JPA)

Some of the cool features provided by Spring Data JPA are:

Spring Data JPA提供的一些很酷的功能是:

  1. Create and support repositories created with Spring and JPA

    创建并支持使用Spring和JPA创建的存储库
  2. Support QueryDSL and JPA queries

    支持QueryDSL和JPA查询
  3. Audit of domain classes

    领域类别的审核
  4. Support for batch loading, sorting, dynamical queries

    支持批量加载,排序,动态查询
  5. Supports XML mapping for entities

    支持实体的XML映射
  6. Reduce code size for generic CRUD operations by using CrudRepository

    通过使用CrudRepository减少通用CRUD操作的代码大小

何时使用Spring Data JPA? (When to use Spring Data JPA?)

I would say that if you need to quickly create a JPA-based repository layer that is mainly for CRUD operations, and you do not want to create abstract DAO, implementing interfaces, Spring Data JPA is a good choice.

我想说的是,如果您需要快速创建主要用于CRUD操作的基于JPA的存储库层,并且不想创建抽象DAO ,实现接口 ,那么Spring Data JPA是一个不错的选择。

Spring Data JPA示例 (Spring Data JPA Example)

For our Spring Data JPA example, we will create a RESTful web service that will connect to Postgresql database. We will implement basic CRUD operations and work on a sample data we already have created.

对于我们的Spring Data JPA示例,我们将创建一个RESTful Web服务 ,该服务将连接到Postgresql数据库。 我们将实现基本的CRUD操作,并处理已经创建的样本数据。

Spring JAP示例样本数据 (Spring JAP Example Sample Data)

Use below query to create table in Postgresql database and add some test data.

使用下面的查询在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 JPA Maven项目结构 (Spring Data JPA Maven Project Structure)

Below image shows the final Spring JPA project structure. We will look into each of the components in detail later on.

Spring Data JPA, Spring JPA Example

下图显示了最终的Spring JPA项目结构。 稍后我们将详细研究每个组件。

Spring Data JPA Maven依赖关系 (Spring Data JPA Maven Dependencies)

We need to add following dependencies for our Spring Data JPA example project.

我们需要为Spring Data JPA示例项目添加以下依赖项。

  1. postgresql: Postgresql java driver.

    postgresql :Postgresql Java驱动程序。
  2. spring-core, spring-context: Spring Framework Core dependencies.

    spring-corespring-contextSpring框架核心依赖项。
  3. spring-webmvc, jackson-databind: For Spring REST application.

    spring-webmvcjackson-databind :用于Spring REST应用程序。
  4. spring-data-jpa, hibernate-entitymanager: for Spring Data JPA and Hibernate support.

    spring-data-jpahibernate-entitymanager :用于Spring Data JPA和Hibernate支持。

Below is content of final pom.xml build file.

以下是最终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配置类 (Spring Configuration Classes)

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 spring annotation says that it is configuration class.

    @Configuration :此Spring注释表示它是配置类。
  • @EnableTransactionManagement: this annotation allows users to use transaction management in application.

    @EnableTransactionManagement :此批注允许用户在应用程序中使用事务管理。
  • @EnableJpaRepositories("com.journaldev.spring.repository"): indicates where the repositories classes are present.

    @EnableJpaRepositories("com.journaldev.spring.repository") :指示存在存储库类的位置。
  • @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

    @PropertySource("classpath:database.properties") :表示我们在类路径中有属性文件。 该文件中的值将被注入到环境变量中。 下面显示了database.properties文件的内容。
  • For using Spring Data, first of all we have to configure DataSource bean. Then we need to configure LocalContainerEntityManagerFactoryBean bean. We need this bean to control the entities. In this beans, you must specify the persistence provider i.e. HibernatePersistence in our case.

    为了使用Spring Data,首先我们必须配置DataSource bean。 然后,我们需要配置LocalContainerEntityManagerFactoryBean bean。 我们需要这个bean来控制实体。 在此bean中,您必须指定持久性提供程序,即本例中的HibernatePersistence
  • The next step is to configure bean for transaction management. In our example it’s JpaTransactionManager. Note that without configuring transaction manager we can’t use @Transactional annotation.

    下一步是为事务管理配置bean。 在我们的示例中,它是JpaTransactionManager 。 请注意,如果不配置事务管理器,则无法使用@Transactional 注解

AppInitializer and WebConfig classes are to configure our application as web application without using web.xml file.

AppInitializerWebConfig类用于将我们的应用程序配置为Web应用程序,而不使用web.xml文件。

型号类别 (Model Class)

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
				+ '\'' + '}';
	}
}

Here we have a few new annotations. Let’s talk about them in more detail.

在这里,我们有一些新的注释。 让我们更详细地讨论它们。

  • @Entity: This annotation allows entity manager to use this class and puts it in context.

    @Entity:此注释允许实体管理器使用此类并将其放在上下文中。
  • @Table(name = “people”): associates a class with a table in the database.

    @Table(name =“ people”):将类与数据库中的表相关联。
  • @Id: says that this field is the primary key.

    @Id :表示此字段为主键。
  • @GeneratedValue(strategy = GenerationType.IDENTITY): Defines the strategy for generating the primary key.

    @GeneratedValue(strategy = GenerationType.IDENTITY) :定义生成主键的策略。
  • @Column(name = "age"): denotes a column in the database with which this field will be associated.

    @Column(name = "age") :表示数据库中与该字段关联的一列。

Spring Data JPA存储库 (Spring Data JPA Repository)

Next step is to create the JPA repository.

下一步是创建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);
}

By inheriting from CrudRepository, we can call many methods without the need to implement them ourself. Some of these methods are:

通过从CrudRepository继承,我们可以调用许多方法,而无需自己实现。 其中一些方法是:

  • save

    保存
  • findOne

    找一个
  • exists

    存在
  • findAll

    找到所有
  • count

    计数
  • delete

    删除
  • deleteAll

    删除所有

We can also define our own methods. These method names should use special keywords such as “find”, “order” with the name of the variables. Spring Data JPA developers have tried to take into account the majority of possible options that you might need. In our example findByFirstName(String firstName) method returns all entries from table where field first_name equals to firstName.

我们还可以定义自己的方法。 这些方法名称应使用特殊关键字,例如“ find”,“ order”和变量名称。 Spring Data JPA开发人员已尝试考虑您可能需要的大多数可能选项。 在我们的示例中, findByFirstName(String firstName)方法返回表中字段first_name等于firstName所有条目。

This is one of the most important feature of Spring Data JPA because it reduces a lot of boiler plate code. Also the chances of errors are less because these Spring methods are well tested by many projects already using them.

这是Spring Data JPA最重要的功能之一,因为它减少了很多样板代码。 而且,由于许多已经使用它们的项目都对这些Spring方法进行了很好的测试,因此出错的可能性也较小。

Spring服务班 (Spring Service Class)

Now that our Spring Data JPA code is ready, next step is to create service class and define methods that we will have to work with database table.

现在我们的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.

@Transactional批注指示该方法将在事务中执行。 Spring将负责事务管理。

弹簧控制器类 (Spring Controller Class)

Final step is to create the controller class to expose our APIs to outer world.

最后一步是创建控制器类,以将我们的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 Data JPA测试 (Spring Data JPA Testing)

Just build and deploy the project into your favorite servlet container such as Tomcat. Below images show the response for some of the API calls.

只需将项目构建并部署到您喜欢的servlet容器(例如Tomcat)中即可。 下图显示了一些API调用的响应。

Spring Data JPA阅读全部 (Spring Data JPA Read All)
Spring Data JPA按名称获取 (Spring Data JPA Get By Name)
Spring Data JPA创建 (Spring Data JPA Create)
Spring Data JPA更新 (Spring Data JPA Update)
Spring Data JPA删除 (Spring Data JPA Delete)

That’s all for Spring Data JPA example tutorial. You can download the final project from below link.

这就是Spring Data JPA示例教程的全部内容。 您可以从下面的链接下载最终项目。

Reference: Official Website

参考: 官方网站

翻译自: https://www.journaldev.com/17034/spring-data-jpa

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值