Spring Data JPA教程

在Java类或对象与关系数据库之间管理数据是一项非常繁琐且棘手的任务。 DAO层通常包含许多样板代码,应简化这些样板代码,以减少代码行数并使代码可重复使用。

在本教程中,我们将讨论Spring数据的JPA实现。

1.简介

1.1什么是JPA?

JPA或Java Persistence API是Java规范,用于访问,管理和持久化Java类或对象与关系数据库之间的数据。 该规范是EJB 3.0的一部分。

JPA不是实现或产品,它只是一个规范。 它包含需要实现的一组接口。 它是一个框架,为JPA实现提供了额外的抽象层。 存储库层将包含三层,如下所述。

  • Spring Data JPA:–提供Spring数据存储库接口,这些接口可用于创建JPA存储库。
  • Spring Data Commons:–它提供了在特定于数据存储的spring数据项目之间共享的基础结构。
  • 实现JPA持久性API的JPA提供程序。

Spring数据JPA允许我们不添加任何存储库层来编写任何样板代码。

1.2 JPA的历史

JPA2.0:– JPA2.0的开发始于2007年,名称为JSR317。该版本被标记为2.0,因为无法获得1.0的共识。 重点是解决著名供应商ORM所提供的功能。

JPA 2.1: -JPA2.1于2011年7月作为JSR 338开始。一些主要功能是实体图,存储过程,转换器等。

JPA 2.2: -JPA2.2是2017年JPA系列的最新功能。它包括对Java 8日期和时间类型的支持以及流查询结果的功能。

JPA仍在进行大量更改,我们可以期待不久的JPA的更新版本。

1.3 Spring数据仓库

Spring Data Commons项目提供了存储库抽象,该存储库抽象由特定于数据存储的子项目扩展。

我们必须熟悉Spring Data仓库接口,因为它将帮助我们实现接口。 让我们看一下接口。

Spring Data Commons:–作为该项目的一部分,提供了以下接口:

  • Repository<T, ID extends Serializable> :此接口是标记接口。
    1. 它捕获托管实体的类型和实体ID的类型。
    2. 扫描类路径时,它可以帮助Spring容器发现“具体的”存储库接口。
  • CrudRepository<T, ID extends Serializable> :它为受管实体提供CRUD操作。
  • PagingAndSortingRepository<T, ID extends Serializable> :此接口声明用于对从数据库中检索到的实体进行排序和分页的方法。
  • QueryDslPredicateExecutor<T> :它不是“存储库接口”。 它声明使用QueryDsl 谓词对象从数据库检索实体的方法。

Spring Data JPA:–该项目提供以下接口:

  • JpaRepository<T, ID extends Serializable> :此接口是JPA特定的存储库接口,它将公共存储库接口声明的方法组合在单个接口后面。
  • JpaSpecificationExecutor<T> :再次不是“存储库接口”。 它声明使用通过使用JPA标准API的Specification<T>对象从数据库检索实体的方法。

存储库层次结构如下所示:

Spring数据存储库层次结构

让我们尝试通过一个示例程序来了解Spring Data JPA。

1.4 Spring数据自定义查询

让我们考虑一个用例,其中我们必须基于查询从数据库中获取数据。 编写自定义查询是非常有用的情况。 Spring Data JPA具有不同的编写自定义查询的方式。 我们将大致分类如下所述的方式。

自动自定义查询:自动自定义查询的创建也称为从方法名称查询创建。 Spring Data JPA具有用于查询创建的内置机制,可用于直接从查询方法的方法名称解析查询。 该机制首先从方法名称中删除公共前缀,并从其余方法名称中解析查询的约束。 为了使用这种方法,我们必须确保通过合并实体对象的属性名称和支持的关键字来创建存储库接口的方法名称。

使用这种方法的优点是它很容易实现。 但是限制是,如果查询包含多个参数,则方法名将不可读。 同样,JPA不支持的关键字(例如lower)也不适用于此方法。

手动自定义查询:手动自定义查询也称为使用@Query标记创建查询。 @Query批注将用于使用JPA查询语言创建查询,并将这些查询直接绑定到存储库接口的方法。 调用查询方法时,Spring Data JPA将执行@Query注释指定的查询。

这种方法的优点是您可以使用JPA查询语言来创建查询。 此外,查询仍位于存储库层。 这种方法的局限性是@Query只能在支持JPA查询语言时使用。

下面提到的程序使用这两种方法。

1.5 Spring Data JPA异常转换

需要考虑的重点是因为默认的Spring ORM模板未与SPring JPA一起使用,是否通过使用Spring Data JPA丢失了异常转换?是否不将JPA异常转换为Spring的DataAccessException层次结构?

答案是否定的 。 通过在DAO上使用@Repository批注,仍可以启用异常转换。 注释使Spring Bean后处理器可以为所有@Repository Bean提供在Container中找到的所有PersistenceExceptionTranslator实例的建议,并像以前一样提供异常转换。

2.工具与技术

让我们看看用于构建程序的技术和工具。

  • Eclipse Oxygen.2发布(4.7.2)
  • Java –版本9.0.4
  • Maven – 3.5.3
  • Spring启动– 2.0.1-发布
  • PostgreSQL – 10
  • 邮差

3.项目结构

我们的项目结构如下图所示。

Spring Data JPA教程的项目结构

上面的项目结构使用的是Maven。 也可以使用Gradle创建该项目,并且pom.xml将替换为build.gradle文件。 该项目的结构将稍微延迟使用Gradle进行构建。

4.方案目标

作为程序的一部分,我们将尝试使用spring boot创建一个简单的Web服务。 该Web服务将用于PostgreSQL数据库上的数据操作。

4.1 pom.xml

该程序的pom.xml文件如下所示。

使用Spring Boot的SpringData JPA的pom.xml

<?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.springjpa</groupId><artifactId>SpringJPA-PostgreSQL</artifactId><version>0.0.1</version><packaging>jar</packaging><name>SpringJPA-PostgreSQL</name><description>Demo project for Spring Boot JPA - PostgreSQL</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.1.RELEASE</version><relativePath/> </parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.9</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.postgresql</groupId><artifactId>postgresql</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.0</version>
</dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

pom.xml文件将包含程序需要的依赖项。

4.2应用类别

对我们来说,Application.java类是SpringJpaPostgreSqlApplication.java类。 该类如下所示。

Spring Boot的SpringJpaPostgreSqlApplication.java类

package com.tutorial;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import com.tutorial.repo.EmployeeRepository;@SpringBootApplication
public class SpringJpaPostgreSqlApplication implements CommandLineRunner{@AutowiredEmployeeRepository repository;public static void main(String[] args){SpringApplication.run(SpringJpaPostgreSqlApplication.class, args);}public void run(String... args) throws Exception {// TODO Auto-generated method stub}}

CommandLineRunner接口用于指示当bean包含在Spring Application中时应运行。

4.3模型类别

我们将创建一个Employee.java类作为模型类。 该类如下所示。

程序的模型类

package com.tutorial.model;import java.io.Serializable;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 = "employee")
public class Employee implements Serializable {private static final long serialVersionUID = -3009157732242241606L;@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name="id")private long id;@Column(name = "firstname")private String firstName;@Column(name = "lastname")private String lastName;@Column(name = "age")private int age;protected Employee() {}public Employee(String firstName, String lastName,int age) {this.firstName = firstName;this.lastName = lastName;this.age = age;}@Overridepublic String toString() {return String.format("Employee[id=%d, firstName='%s', lastName='%s', age='%d']", id, firstName, lastName,age);}public long getId() {return id;}public void setId(long id) {this.id = id;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLast_Name(String lastName) {this.lastName = lastName;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

@Entity :用于定义该类为Entity类。
@Table :此批注用于指定数据库中定义的表名。
@Id :Id注释用于指定Id属性 @GeneratedValue :当我们要设置自动生成的值时使用。 GenerationType是用于生成特定列的值的机制。 @Column :此批注用于将表中的列与类中的属性进行映射。

4.4储存库接口

存储库接口用于扩展CRUD接口。 该接口在程序中添加了存储库层。 Spring Data JPA提供了两种创建查询的主要方法。 然后,在存储库界面中使用这些查询来从数据库中获取数据。

用于扩展CRUD存储库的存储库类

package com.tutorial.repo;import java.util.List;import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;import com.tutorial.model.Employee;@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Long>{List findByLastName(String lastName);@Query("SELECT e FROM Employee e WHERE e.age = :age")public List findByAge(@Param("age") int age);
}

CrudRepositoryCrudRepository Common项目的接口。 上面提到的两种用于查询创建的方法在代码的以下位置使用。

自动自定义查询:

List findByLastName(String lastName);

方法findByLastName包含姓氏作为参数,将用于数据搜索。 另外,将使用JPA查询构建器自动创建查询。

手动自定义查询:

@Query("SELECT e FROM Employee e WHERE e.age = :age")public List findByAge(@Param("age") int age);

在此方法中,我们手动定义了一个查询以根据年龄取数据,然后将查询与findByAge方法绑定。

4.5属性文件

作为用于连接数据库的Spring Boot的一部分,我们将在属性文件中提供详细信息。 属性文件如下所示。

Spring启动的application.properties文件

spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=password
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

作为属性文件的一部分,提供了数据库URL和凭据。 属性spring.jpa.show-sql=true显示JPA进行数据操作期间生成的SQL查询。

4.6控制器等级

控制器是整个程序中最重要的一类。 这是负责所有url映射的类。 我们在此类本身中添加了用于数据操作的存储库方法。

程序的控制器类

package com.tutorial.controller;import java.util.List;
import java.util.Optional;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.tutorial.model.Employee;
import com.tutorial.repo.EmployeeRepository;@RestController
@RequestMapping("/employee")
public class WebController {@AutowiredEmployeeRepository repository;@RequestMapping(value="/save",method = RequestMethod.POST)public HttpStatus insertEmployee(@RequestBody Employee employee){boolean status = repository.save(employee) != null;		return status? HttpStatus.CREATED : HttpStatus.BAD_REQUEST;}@RequestMapping("/findall")public List findAll(){return (List) repository.findAll();}@RequestMapping("/findbyid")public Optional findById(@RequestParam("id") long id){Optional result = repository.findById(id);return result;}@RequestMapping("/findbylastname")public List fetchDataByLastName(@RequestParam("lastname") String lastName){return repository.findByLastName(lastName);}@RequestMapping("/findbyage")public List fetchDataByAge(@RequestParam("age") int age){return repository.findByAge(age);}
}

@RestController标记用于将类定义为rest控制器类。
@RequestMapping标记指定请求的路径映射。 值属性指定URL映射,方法属性指定它的方法类型,例如GET,POST,PUT等。
如果默认情况下不指定method属性,则该方法被视为GET方法。

在此类中,我们已自动连接存储库,并使用界面中可用的方法进行数据检索,插入和删除。

为了运行spring boot应用程序,我们必须提供命令spring-boot: run

5.输出

下面提到的查询可用于在PostgreSQL中创建Employee表。

用于查询Employee表的SQL查询

create table employee (
id serial not null primary key,
firstName varchar(20) not null,
lastName varchar(20) not null,
age integer not null
);

让我们检查数据库中可用的数据。 数据库中的当前可用数据如下所示。

PostgreSQL中的数据

现在,让我们尝试使用postman集合来查找findall API,以获取结果行。 结果将如下所示在邮递员上。

Findall API在邮递员上的结果

为了在数据库中添加一些雇员对象。 我们将使用save API并将传递一个employee对象。

使用保存API将对象存储在DB中

让我们检查数据库中保存API的用法。 该数据库将如下所示。

使用Save API保存数据后

同样,我们可以使用findbylastname API来查找具有request参数中提供的姓氏的记录。

findbylastname API的结果

让我们看看绑定到手动自定义查询的方法的结果。

findByAge API的结果

6.总结

本教程的摘要在下面提到。

  1. SpringData JPA提供了用于JPA持久性API的存储库抽象。
  2. 我们了解了CRUD存储库的用法。
  3. 我们使用自动自定义查询来基于姓氏搜索行。
  4. 我们了解了手动定制查询的创建。
  5. JPA异常翻译取决于@Repository标记。

7.下载Eclipse项目

这是使用SpringBoot的SpringData JPA教程。

您可以在此处下载此示例的完整源代码: SpringJPA-PostgreSQL.zip

翻译自: https://www.javacodegeeks.com/2018/05/spring-data-jpa-tutorial.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用storm 实时计算_使用Storm进行可扩展的实时状态更新

使用storm 实时计算在本文中&#xff0c;我将说明如何借助Storm框架以可扩展且无锁定的方式在数据库中维护实时事件驱动流程的当前状态。 Storm是基于事件的数据处理引擎。 它的模型依赖于基本原语&#xff0c;例如事件转换&#xff0c;过滤&#xff0c;聚合……&#xff0c;我…

【多元域乘法】多项式乘法电路原理及MATLAB详解

关注公号【逆向通信猿】更精彩!!! 关于二元域上的两个元素的乘法、多项式除法,在之前的博客 【有限域除法】二元多项式除法电路原理及MATLAB详解 子程序:sub_poly_div.m 【有限域元素加法和乘法】有限域元素加法和乘法的原理及MATLAB实现 子程序:sub_gf_add.m、sub_gf_…

my CSAPP Attack lab堆栈详解

关注公号【逆向通信猿】更精彩!!! 这个实验时学习了简书上的一篇文章后,自己根据课程例子进行的一次小测试,phase 4和5的堆栈图解还没有画,等后续有时间会进行补充。 本人转载的简书原文: https://blog.csdn.net/wlwdecs_dn/article/details/121249364#comments_19237…

Spring MVC教程

1.简介 作为企业Java开发人员&#xff0c;这项工作的主要重点之一是开发Web应用程序。 对于Web应用程序&#xff0c;后果还包括许多挑战。 具体来说&#xff0c;其中一些是状态管理&#xff0c;工作流和验证。 HTTP协议的无状态性质只会使事情变得更加复杂。 Spring的Web框架旨…

ubuntu22.04 下载路径

ftp下载路径 csdn下载 ubuntu22.04下载路径ubuntu-22.04-desktop-amd64.7z.001资源-CSDN文库 ubuntu22.04下载路径ubuntu-22.04-desktop-amd64.7z.002资源-CSDN文库 【免费】ubuntu-22.04-desktop-amd64.7z.003资源-CSDN文库 【免费】ubuntu-22.04-desktop-amd64.7z.004资源-…

Spring Reactor教程

在RESTful服务的世界中&#xff0c;实际上实际上是在幕后进行许多工作&#xff0c;我们通常必须在应用程序中进行很多处理&#xff0c;而实际上并不会影响需要发送给真实用户的响应。 可以被动地做出这些业务决策&#xff0c;以便它们对与应用程序交互的用户没有任何影响。 Spr…

api签名_使用签名保护基于HTTP的API

api签名我在EMC上的一个平台上可以构建SaaS解决方案。 与越来越多的其他应用程序一样&#xff0c;该平台具有基于RESTful HTTP的API。 使用JAX-RS之类的开发框架&#xff0c;构建这样的API相对容易。 但是&#xff0c; 正确构建它们并不容易。 建立基于HTTP的API的问题 问…

【多元域除法】多项式除法电路原理及MATLAB详解

关注公号【逆向通信猿】更精彩!!! 关于二元域上的两个元素的加法和乘法、多项式除法,在之前的博客 【有限域除法】二元多项式除法电路原理及MATLAB详解 子程序:sub_poly_div.m 【有限域元素加法和乘法】有限域元素加法和乘法的原理及MATLAB实现 子程序:sub_gf_add.m、s…

win10高分辨率下修改字体显示大小(不是缩放百分比)

问题 不通过修改设置缩放百分比来增大win10的字体显示大小&#xff0c;缩放百分比调大后会导致很多问题出现&#xff01;&#xff01;&#xff01; 修改 打开设置&#xff0c;或者右键个性化&#xff0c;在搜索栏输入&#xff1a;“放大文本大小”&#xff0c;搜索框下面会自…

应用程序无法正常启动 0xc0150002

Visual Studio 2017在debug下运行程序报错 应用程序无法正常启动 0xc0150002 分析原因 可能是&#xff1a;原程序是低版本的VS所编写的&#xff0c;缺少低版本的运行库&#xff0c;所以报错 解决 安装了VS2010后即可正常运行 error LNK2019: 无法解析的外部符号 __vsnwprin…

Excel之抽奖器实现

Excel实现一个抽奖器&#xff0c;关键在于学会几个Excel中的函数即可轻松实现。 单人抽奖 RANDBETWEEN 例&#xff1a; INDEX(A2:A61,RANDBETWEEN(1,60))缺点&#xff1a;这种方式生成的抽奖器&#xff0c;在多人情况下&#xff0c;由于RANDBETWEEN函数的返回值有可能是相同…

【RS码1】系统RS码编码原理及MATLAB实现(不使用MATLAB库函数)

关注公号【逆向通信猿】更精彩!!! 基础知识 要想搞懂本节知识,需要先熟悉掌握以下前几篇博客 【多元域乘法】多项式乘法电路原理及MATLAB详解 【多元域除法】多项式除法电路原理及MATLAB详解 RS码编码原理 RS码的编码与BCH码类似,区别在于RS码为多进制的 生成多项式…

如何用Java编写类似C的Sizeof函数

如果您刚开始学习Java并且是C语言背景&#xff0c;那么您可能已经注意到Java和C编程语言之间存在一些差异&#xff0c;例如String是Java中的对象&#xff0c;而不是NULL终止的字符数组。 同样&#xff0c;Java中没有sizeof&#xff08;&#xff09;运算符。 所有原始值都有预定…

Spring启动教程

1.简介 如果您一直想使用一个Web框架&#xff0c;它使您能够快速开始API开发&#xff0c;而无须设置Web服务器&#xff0c;收集所有有线依赖项&#xff0c;安装各种工具的麻烦&#xff0c;那么您将拥有一个出色的框架&#xff0c;即Spring开机 Spring Boot的主要座右铭是约定优…

【LDPC系列1】基于MATLAB中LDPC编译码器对象的图像传输通信系统仿真

关注公号【逆向通信猿】更精彩!!! 1. 构造编码器对象 采用MATLAB内置的comm.LDPCEncoder构造编码器对象,其中使用默认的校验矩阵,信息位长32400比特,码长64800比特,该校验矩阵中除第一行中1的个数为6个外,其余行中1的个数均为7;前12960列中1的个数为8,后32400列构成…

【LDPC系列2】基于MATLAB中LDPC编译码器对象的图像传输通信系统仿真(IEEE 802.16e标准协议基础矩阵)

关注公号【逆向通信猿】更精彩!!! 1. 构造校验矩阵H,并保存为mat文件 采用IEEE 802.16e标准协议中的基础校验矩阵 通过构造QC-LDPC校验矩阵,码长n=2304,信息长k=1152,码率r=1/2,基础矩阵维数为1224: Hb = [-1 94 73 -1

VS2010附加进程调试DLL时断点无法断下的解决方法

系统版本&#xff1a;Win10 x64 1809 VS版本&#xff1a;VS2017 企业版 问题一 在动态链接库(DLL)附加到进程调试时&#xff0c;用VS2017附加后单步调试&#xff0c;结果发现总是在调试过程中卡死&#xff0c;VS2017无响应&#xff1b; 解决办法是&#xff1a;强制结束VS2017…

用于SaaS和NoSQL的Jdbi

一个自然的接口&#xff0c;用于与CRM&#xff0c;ERP&#xff0c;会计&#xff0c;营销自动化&#xff0c;NoSQL&#xff0c;平面文件等基于Java的数据集成 Jdbi是Java的SQL便利库&#xff0c;它为JDBC提供更自然的Java数据库接口&#xff0c;该接口易于绑定到域数据类型。 该…

【卷积码系列3】(n,k,m)卷积码的维特比译码实现(不使用MATLAB库函数)及性能对比(vitdec函数不使用MATLAB库函数【全部代码需私信另外付费获取】)

理论基础 MATLAB库函数polly2trellis(卷积码生成多项式转网格图描述)的实现过程详解 上面这篇仅作为了解!!! 【卷积码系列1】(n,k,m)卷积码的编码原理详解及MATLAB实现 【卷积码系列2】(n,k,m)卷积码的生成多项式矩阵系数转网格图描述(不使用MATLAB库函数) 维特比译码曲…

Java批处理教程

在当今世界&#xff0c;互联网已经改变了我们的生活方式&#xff0c;其主要原因之一是大多数日常琐事都使用互联网。 这导致可用于处理的大量数据。 其中涉及大量数据的一些示例是处理工资单&#xff0c;银行对帐单&#xff0c;利息计算等。因此&#xff0c;请设想一下&#x…