在本教程中,我们将学习如何使用SpringDataJPA(Hibernate作为JPA提供者)执行一对多域模型映射。
查看Spring Data JPA one to many bidirectional mapping上的一对多双向映射教程
单向的一对多关联更简单,因为它只是定义关系的父端。在单向映射中,我们只使用@OneToMany
注解。
查看我的Udemy课程学习春季数据JPA:Master Spring Data JPA with Hibernate
在关系数据库系统中,一对多关联基于外键列链接两个表,以便子表记录引用父表行的主键。
SpringBoot提供了一个名为https://start.spring.io的web工具来快速引导应用程序。只需转到https://start.spring.io并生成一个新的spring-boot项目。
在创建Spring引导时使用以下详细信息:
**项目名称:**Spring Data jpa课程
**项目类型:**Maven
**选择依赖项:**Spring Data JPA、MySQL Driver、Lombok
**软件包名称:**net.javaguides.springboot
这是完整的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>net.javaguides</groupId>
<artifactId>spring-data-jpa-course</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-data-jpa-course</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在本例中,让我们使用MySQL数据库存储和检索数据,并使用Hibernate属性创建和删除表。
打开应用程序。属性文件,并向其中添加以下配置:
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false
spring.datasource.username=root
spring.datasource.password=Mysql@123
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = create-drop
确保在运行Spring引导应用程序之前创建一个演示数据库。
此外,根据您机器上的MySQL安装更改MySQL用户名和密码。
让我们在基本包“net.javaguides.springboot”中创建一个实体包。
在实体包中,创建包含以下内容的Order和OrderItems类:
package net.javaguides.springdatajpacourse.entity;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name="orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@Column(name="order_tracking_number")
private String orderTrackingNumber;
@Column(name="total_quantity")
private int totalQuantity;
@Column(name="total_price")
private BigDecimal totalPrice;
@Column(name="status")
private String status;
@Column(name="date_created")
@CreationTimestamp
private Date dateCreated;
@Column(name="last_updated")
@UpdateTimestamp
private Date lastUpdated;
// one to many unidirectional mapping
// default fetch type for OneToMany: LAZY
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "order_id", referencedColumnName = "id")
private Set<OrderItem> orderItems = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOrderTrackingNumber() {
return orderTrackingNumber;
}
public void setOrderTrackingNumber(String orderTrackingNumber) {
this.orderTrackingNumber = orderTrackingNumber;
}
public int getTotalQuantity() {
return totalQuantity;
}
public void setTotalQuantity(int totalQuantity) {
this.totalQuantity = totalQuantity;
}
public BigDecimal getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
public Set<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(Set<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public void add(OrderItem item) {
if (item != null) {
if (orderItems == null) {
orderItems = new HashSet<>();
}
orderItems.add(item);
// item.setOrder(this);
}
}
public BigDecimal getTotalAmount()
{
BigDecimal amount = new BigDecimal("0.0");
for (OrderItem item : this.orderItems)
{
amount = amount.add(item.getPrice());
}
return amount;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", orderTrackingNumber='" + orderTrackingNumber + '\'' +
", totalQuantity=" + totalQuantity +
", totalPrice=" + totalPrice +
", status='" + status + '\'' +
", dateCreated=" + dateCreated +
", lastUpdated=" + lastUpdated +
'}';
}
}
package net.javaguides.springdatajpacourse.entity;
import javax.persistence.*;
import java.math.BigDecimal;
@Entity
@Table(name="order_items",schema = "ecommerce")
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@Column(name="image_url")
private String imageUrl;
@Column(name = "price")
private BigDecimal price;
@Column(name="quantity")
private int quantity;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
接下来我们要做的是创建存储库,以便从数据库访问Order实体。
JpaRepository接口定义了实体上所有CRUD操作的方法,以及名为SimpleJpaRepresitory的JpaReppository的默认实现。
让我们在基本包“net.javaguides.springdatarest”中创建一个存储库包。
在存储库包中,创建一个包含以下内容的OrderRepository界面:
package net.javaguides.springdatajpacourse.repository;
import net.javaguides.springdatajpacourse.entity.Order;
import org.springframework.data.jpa.repository.JpaRepository;
public interface OrderRepository extends JpaRepository<Order, Long>{
Order findByOrderTrackingNumber(String orderTrackingNumber);
}
让我们编写JUnit测试,使用Spring Data JPA对一对多单向映射执行CRUD操作:
package net.javaguides.springdatajpacourse.repository;
import net.javaguides.springdatajpacourse.entity.Order;
import net.javaguides.springdatajpacourse.entity.OrderItem;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class OneToManyUnidirectionalMappingTest {
@Autowired
private OrderRepository orderRepository;
@Test
void testSaveOrder(){
// create Order object
Order order = new Order();
OrderItem orderItem = new OrderItem();
orderItem.setImageUrl("image_url.png");
orderItem.setPrice(new BigDecimal(100));
// add orderitem to order
order.add(orderItem);
OrderItem orderItem2 = new OrderItem();
orderItem2.setImageUrl("image_url.png");
orderItem2.setPrice(new BigDecimal(200));
// add orderItem2 to order
order.add(orderItem2);
order.setOrderTrackingNumber("1000");
order.setStatus("IN PROGRESS");
// total amount of the order
order.setTotalPrice(order.getTotalAmount());
// Quantity of the order items
order.setTotalQuantity(2);
orderRepository.save(order);
}
@Test
void testUpdateOrder(){
Order order = orderRepository.findById(1L).get();
order.setStatus("DELIVERED");
orderRepository.save(order);
}
@Test
void testGetAllOrders(){
List<Order> orders = orderRepository.findAll();
orders.forEach((o) -> {
System.out.println("order id :: " + o.getId());
o.getOrderItems().forEach((orderItem -> {
System.out.println("orderItem :: " + orderItem.getId());
}));
});
}
@Test
void testFindByOrderTrackingNumber(){
Order order = orderRepository.findByOrderTrackingNumber("1000");
// add fetch type as EAGER
// order.getOrderItems().forEach((o) -> {
// System.out.println(o.getId());
// });
}
@Test
void testDeleteOrder(){
orderRepository.deleteById(1L);
}
}
@Test
void testSaveOrder(){
// create Order object
Order order = new Order();
OrderItem orderItem = new OrderItem();
orderItem.setImageUrl("image_url.png");
orderItem.setPrice(new BigDecimal(100));
// add orderitem to order
order.add(orderItem);
OrderItem orderItem2 = new OrderItem();
orderItem2.setImageUrl("image_url.png");
orderItem2.setPrice(new BigDecimal(200));
// add orderItem2 to order
order.add(orderItem2);
order.setOrderTrackingNumber("1000");
order.setStatus("IN PROGRESS");
// total amount of the order
order.setTotalPrice(order.getTotalAmount());
// Quantity of the order items
order.setTotalQuantity(2);
orderRepository.save(order);
}
@Test
void testUpdateOrder(){
Order order = orderRepository.findById(1L).get();
order.setStatus("DELIVERED");
orderRepository.save(order);
}
@Test
void testGetAllOrders(){
List<Order> orders = orderRepository.findAll();
orders.forEach((o) -> {
System.out.println("order id :: " + o.getId());
o.getOrderItems().forEach((orderItem -> {
System.out.println("orderItem :: " + orderItem.getId());
}));
});
}
@Test
void testDeleteOrder(){
orderRepository.deleteById(1L);
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.javaguides.net/2022/02/spring-data-jpa-one-to-many-unidirectional-mapping.html
内容来源于网络,如有侵权,请联系作者删除!