Spring boot教程-Spring Boot JPA
Spring Boot JPA
什么是JPA?
Spring Boot JPA是用于在Java应用程序中管理关系型数据的Java规范。它允许我们在Java对象/类和关系型数据库之间访问和持久化数据。JPA遵循对象关系映射(ORM)。它是一组接口。它还提供了一个运行时的EntityManager API,用于对数据库中的对象执行查询和事务。它使用平台无关的面向对象查询语言JPQL(Java持久化查询语言)。
在持久化的上下文中,它涵盖了三个领域:
- Java持久化API
- 对象-关系元数据
- API本身,定义在持久化包中
JPA不是一个框架。它定义了一个概念,可以由任何框架来实现。
为什么要使用JPA?
JPA比JDBC、SQL和手写映射更简单、更清洁,工作量更小。JPA适用于非性能导向的复杂应用程序。JPA相对于JDBC的主要优势在于,在JPA中,数据由对象和类表示,而在JDBC中,数据由表和记录表示。它使用POJO来表示持久化数据,简化了数据库编程。JPA还有其他优点:
- JPA避免了在特定于数据库方言的DDL中编写。相反,它允许在XML中进行映射,或使用Java注释。
- JPA允许我们避免在特定于数据库方言的DML中编写。
- JPA允许我们在根本不使用任何DML语言的情况下保存和加载Java对象和图形。
- 当我们需要执行JPQL查询时,它允许我们根据Java实体而不是(本地)SQL表和列来表达查询。
JPA特性
JPA具有以下特性:
- 它是一个功能强大的存储库和自定义对象映射抽象。
- 支持跨存储持久化。这意味着实体可以部分存储在MySQL和Neo4j(图形数据库管理系统)中。
- 它可以从查询方法名称动态生成查询。
- 领域基类提供基本属性。
- 支持透明审计。
- 可以集成自定义存储库代码。
- 可以与Spring框架轻松集成,使用自定义命名空间。
JPA架构
JPA是将业务实体存储为关系实体的源代码。它展示了如何将POJO定义为实体,并如何使用关系管理实体。
以下图表描述了JPA的类级架构,描述了JPA的核心类和接口,这些类和接口定义在javax.persistence包中。JPA架构包含以下单元:
JPA类关系
上述我们讨论的类和接口之间保持着一种关系。以下图表显示了类和接口之间的关系。
- EntityManager和EntityTransaction之间的关系是一对一的。每个EntityManager操作都由EntityTransaction类维护。
- EntityManageFactory和EntityManager之间的关系是一对多的。它是EntityManager实例的工厂类。
- EntityManager和Query之间的关系是一对多的。我们可以使用EntityManager类的实例执行任意数量的查询。
- EntityManager和Entity之间的关系是一对多的。一个EntityManager实例可以管理多个实体。
JPA实现
JPA是一个开源的API。有各种企业供应商,例如Eclipse、RedHat、Oracle等,它们通过将JPA添加到它们的产品中来提供新的产品。一些流行的JPA实现框架包括Hibernate、EclipseLink、DataNucleus等。它也被称为对象-关系映射(ORM)工具。
对象-关系映射(ORM)
在ORM中,将Java对象映射到数据库表,反之亦然,称为对象关系映射。ORM映射作为连接关系型数据库(表和记录)和Java应用程序(类和对象)之间的桥梁。
在下图中,ORM层是一个适配器层。它将对象图的语言适配为SQL语言和关系表的语言。
ORM层存在于应用程序和数据库之间。它将Java类和对象转换为可以存储和管理在关系型数据库中的形式。默认情况下,持久化的名称成为表的名称,字段成为列。一旦应用程序设置好,每个表行对应一个对象。
JPA版本
早期的EJB版本通过javax.ejb.EntityBean接口定义了将持久层与业务逻辑层组合在一起的方法。EJB规范包括了JPA的定义。
在引入EJB 3.0时,持久层被分离并被指定为JPA 1.0(Java持久化API)。这个API的规范是与JAVA EE5的规范一起于2006年5月11日发布的,使用了JSR 220。
在2019年,JPA更名为Jakarta Persistence。JPA的最新版本是2.2。它支持以下功能:
- Java 8、日期和时间API
- 在AttributeConvertes中进行CDI注入
- 它使注释变为可重复使用的
JPA与Hibernate的区别
JPA: JPA是用于在Java应用程序中管理关系数据的Java规范。它是ORM的标准方法。
Hibernate: 它是一个轻量级、开源的ORM工具,用于在关系型数据库系统中存储Java对象。它是JPA的提供者。它遵循JPA提供的通用方法。
以下表格描述了JPA和Hibernate之间的区别。
JPA | Hibernate |
---|---|
JPA是用于在Java应用程序中映射关系数据的Java规范。 | Hibernate是用于数据持久化的ORM框架。 |
JPA不提供任何实现类。 | 它提供实现类。 |
它使用平台无关的查询语言JPQL(Java持久化查询语言)。 | 它使用自己的查询语言HQL(Hibernate查询语言)。 |
它定义在javax.persistence包中。 | 它定义在org.hibernate包中。 |
它在各种ORM工具中实现,如Hibernate、EclipseLink等。 | Hibernate是JPA的提供者。 |
JPA使用EntityManager来处理数据的持久化。 | Hibernate使用Session来处理数据的持久化。 |
Spring Boot Starter Data JPA
Spring Boot提供了起始依赖项spring-boot-starter-data-jpa,以便有效地将Spring Boot应用程序与关系数据库连接起来。spring-boot-starter-data-jpa在内部使用spring-boot-jpa依赖项。
在Spring Boot中,我们可以很容易地将Apache Derby数据库集成到应用程序中,只需在pom.xml文件中添加Derby依赖项即可。
以上是关于Spring Boot JPA的一些基本概念和用法的说明。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
Spring Boot JPA示例
让我们创建一个使用JPA连接到数据库的Spring Boot应用程序示例。在以下示例中,我们使用了内存数据库Apache Derby。
Apache Derby:*它是一个完全由Java实现的*开源嵌入式关系型数据库。它在Apache许可证2.0下提供。Apache Derby的优势如下:
- 安装、部署和使用都很容易。
- 基于Java、JDBC和SQL标准。
- 提供嵌入式JDBC驱动程序,允许我们将Derby嵌入到任何基于Java的解决方案中。
- 还支持使用Derby Network Client JDBC驱动程序和Derby Network Server的客户端/服务器模式。
Spring Boot可以自动配置嵌入式数据库,例如H2、HSQL和Derby数据库。我们不需要提供任何连接URL。我们只需要在pom.xml文件中包含要使用的嵌入式数据库的构建依赖项。
在Spring Boot中,我们可以通过在pom.xml文件中添加Derby依赖项来轻松集成Apache Derby数据库。
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<scope>runtime</scope>
</dependency>
步骤1:打开Spring Initializr https://start.spring.io/
。
步骤2:选择最新版本的Spring Boot 2.3.0(SNAPSHOT)
步骤3:*提供*Group名称。我们提供了cn.javatiku。
步骤4:*提供*Artifact Id。我们提供了apache-derby-example。
步骤5:*添加依赖项:**Spring Web,Spring Data JPA**和*Apache Derby Database。
步骤6:*点击*Generate按钮。当我们点击Generate按钮时,它将项目打包成一个Jar文件并下载到本地系统。
步骤7:解压Jar文件并将其粘贴到STS工作区。
步骤8:将项目文件夹导入到STS中。
File -> Import -> Existing Maven Projects -> Browse -> 选择文件夹apache-derby-example -> Finish
导入需要一些时间。
步骤9:*在文件夹*src/main/java中创建一个名为cn.javatiku.model的包。
步骤10:*在包*cn.javatiku.model中创建一个名为UserRecord的类,并执行以下操作:
- 定义三个变量id,name和email。
- 生成Getter和Setter。 在文件上右键单击-> Source -> Generate Getters and Setters
- 定义默认构造函数。
- 使用注释@Entity将类标记为Entity。
- 使用注释@Id将Id标记为主键。
UserRecord.java
package cn.javatiku.model;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class UserRecord
{
@Id
private int id;
private String name;
private String email;
//default conatructor
public UserRecord()
{
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
}
步骤11:*在文件夹*src/main/java中创建一个名为cn.javatiku.controller的包。
步骤12:*在包*cn.javatiku.controller中创建一个名为UserController的Controller类,并执行以下操作:
- 使用注释@RestController将类标记为控制器。
- 使用注释@Autowired自动装配类UserService。
- 我们定义了两个映射,一个用于获取所有用户,另一个用于add-user。
UserController.java
package cn.javatiku.controller;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import cn.javatiku.model.UserRecord;
import cn.javatiku.service.UserService;
import java.util.List;
@RestController
public class UserController
{
@Autowired
private UserService userService;
@RequestMapping("/")
public List<UserRecord> getAllUser()
{
return userService.getAllUsers();
}
@RequestMapping(value="/add-user", method=RequestMethod.POST)
public void addUser(@RequestBody UserRecord userRecord)
{
userService.addUser(userRecord);
}
}
步骤13:*在文件夹*src/main/java中创建一个名为cn.javatiku.service的包。
步骤14:*在包*cn.javatiku.service中创建一个名为UserService的Service类,并执行以下操作:
- 使用注释@Service将类标记为服务。
- 自动装配UserRepository
- 定义一个名为getAllUsers()的方法,返回一个列表。
- 定义另一个名为addUser()的方法,保存用户记录。
UserService.java
package cn.javatiku.service;
import java.util.List;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.javatiku.model.UserRecord;
import cn.javatiku.repository.UserRepository;
@Service
public class UserService
{
@Autowired
private UserRepository userRepository;
public List<UserRecord> getAllUsers()
{
List<UserRecord>userRecords = new ArrayList<>();
userRepository.findAll().forEach(userRecords::add);
return userRecords;
}
public void addUser(UserRecord userRecord)
{
userRepository.save(userRecord);
}
}
步骤15:*在文件夹*src/main/java中创建一个名为cn.javatiku.repository的包。
步骤16:*在包*cn.javatiku.repository中创建一个名为UserRepository的repository接口,并扩展CrudRepository。
UserRepository.java
package cn.javatiku.repository;
import org.springframework.data.repository.CrudRepository;
import cn.javatiku.model.UserRecord;
public interface UserRepository extends CrudRepository<UserRecord, String>
{
}
步骤17:*现在,打开*ApacheDerbyExampleApplication.java文件。在设置应用程序时默认创建了该文件。
ApacheDerbyExampleApplication.java
package cn.javatiku;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ApacheDerbyExampleApplication
{
public static void main(String[] args)
{
SpringApplication.run(ApacheDerbyExampleApplication.class, args);
}
}
现在,我们根据要求设置了所有必要的类和包。请注意,我们没有为数据库提供任何连接URL。完成所有上述步骤后,项目目录看起来如下所示:
让我们运行应用程序。
步骤18:*打开*ApacheDerbyExampleApplication.java文件,并将其作为Java应用程序运行。
步骤19:在浏览器中打开并调用URL http://localhost:8080/
。它返回一个空列表,因为我们没有在列表中添加任何用户。
要将用户添加到数据库中,我们将通过Postman发送一个POST请求。
步骤20:*打开*Postman,并执行以下操作:
- 选择POST
- 调用URL
http://localhost:8080/add-user
。 - 点击Body
- 选择内容类型为JSON(application/json)。
插入要插入数据库的数据。我们插入了以下数据:
{ "id": "001", "name": "Tom", "email": "tom@gmail.com" }
- 点击Send按钮。
当我们点击Send按钮时,它显示Status:200 OK。这意味着请求已成功执行。
步骤21:在浏览器中打开并调用URL http://localhost:8080/
。它返回我们在数据库中插入的用户。
以上是创建使用Spring Boot和JPA连接到数据库的示例的详细步骤。