Spring Data JPA

时间:2020-02-23 14:35:51  来源:igfitidea点击:

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

Spring Data JPA

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

  • 创建并支持使用Spring和JPA创建的存储库
  • 支持QueryDSL和JPA查询
  • 审核领域类别
  • 支持批量加载,排序,动态查询
  • 支持实体的XML映射
  • 通过使用CrudRepository减少通用CRUD操作的代码大小

何时使用Spring Data JPA?

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

Spring Data JPA示例

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

Spring JAP示例示例数据

使用下面的查询在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 JPA项目结构。
稍后我们将详细研究每个组件。

Spring Data JPA Maven依赖关系

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

  • postgresql:Postgresql Java驱动程序。

  • spring-core,spring-context:Spring框架核心依赖项。

  • spring-webmvc,Hymanson-databind:用于Spring REST应用程序。

  • " spring-data-jpa"," hibernate-entitymanager":用于Spring Data JPA和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.theitroad</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.Hymanson.core</groupId>
			<artifactId>Hymanson-databind</artifactId>
			<version>${serializer.version}</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>${project.artifactId}</finalName>
	</build>
</project>

Spring配置类

package com.theitroad.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.theitroad.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.theitroad.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:这个Spring的注解说它是配置类。

  • @EnableTransactionManagement:此批注允许用户在应用程序中使用事务管理。

  • @EnableJpaRepositories(" com.theitroad.spring.repository")":指示存储库类的位置。

  • @PropertySource(" classpath:database.properties"):表示我们在类路径中有属性文件。
    该文件中的值将被注入到环境变量中。
    下面显示了database.properties文件的内容。

  • 为了使用Spring Data,首先我们必须配置DataSourcebean。
    然后,我们需要配置LocalContainerEntityManagerFactoryBean bean。
    我们需要这个bean来控制实体。
    在这个bean中,您必须指定持久性提供程序,即本例中的" HibernatePersistence"。

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

AppInitializer和WebConfig类用于在不使用web.xml文件的情况下将我们的应用程序配置为Web应用程序。

型号类别

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

其中我们有一些新的注释。
让我们更详细地讨论它们。

  • @Entity:此注释允许实体管理器使用此类并将其放在上下文中。

  • @Table(name =" people"):将类与数据库中的表相关联。

  • @Id:表示该字段是主键。

  • @GeneratedValue(strategy = GenerationType.IDENTITY):定义用于生成主键的策略。

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

Spring Data JPA存储库

下一步是创建JPA存储库。

package com.theitroad.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
				+ '\'' + '}';
	}
}

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

  • 找一个
  • 存在
  • 找到所有
  • 计数
  • 删除
  • 删除所有

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

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

Spring服务班

现在我们的Spring Data JPA代码已经准备就绪,下一步是创建服务类并定义我们必须使用数据库表的方法。

package com.theitroad.spring.repository;

import org.springframework.data.repository.CrudRepository;

import com.theitroad.spring.model.Person;

import java.util.List;

public interface PersonRepository<P> extends CrudRepository<Person, Long> {
  List<Person> findByFirstName(String firstName);
}

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

Spring 控制器类

最后一步是创建控制器类,以将我们的API暴露给外界。

package com.theitroad.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.theitroad.spring.model.Person;
import com.theitroad.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;
	}
}

Spring Data JPA测试

只需将项目构建并部署到您喜欢的servlet容器(例如Tomcat)中即可。