文章目錄
Spring Boot JPA中關聯表的使用
本文中,我們會將會通過一個Book和Category的關聯關系,來講解如何在JPA中使用。
添加依賴
我們還是使用H2內存數據庫來做測試:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
構建Entity
下面我們構建兩個Entity:
@Data
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne
private Category category;
}
@Data
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
private List<Book> books;
}
上面我們定義了兩個Entity,Category和Book是一對多的關系。我們通過@ManyToOne和@OneToMany來定義相應的關系。
構建Repository
我們接下來構建相應的Repository:
public interface BookRepository extends CrudRepository<Book, Long> {
long deleteByTitle(String title);
@Modifying
@Query("delete from Book b where b.title=:title")
void deleteBooks(@Param("title") String title);
}
public interface CategoryRepository extends CrudRepository<Category, Long> {}
構建初始數據
為了方便測試,我們先構建需要的數據schema.sql和data.sql:
CREATE TABLE book (
id BIGINT NOT NULL AUTO_INCREMENT,
title VARCHAR(128) NOT NULL,
category_id BIGINT,
PRIMARY KEY (id)
);
CREATE TABLE category (
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(128) NOT NULL,
PRIMARY KEY (id)
);
insert into book(id,title,category_id)
values(1,'The Hobbit',1);
insert into book(id,title,category_id)
values(2,'The Rabbit',1);
insert into category(id,name)
values(1,'category');
測試
我們看一下怎么從Book中刪除一條數據:
@Test
public void whenDeleteByIdFromRepository_thenDeletingShouldBeSuccessful() {
assertThat(bookRepository.count()).isEqualTo(2);
bookRepository.deleteById(1L);
assertThat(bookRepository.count()).isEqualTo(1);
}
再看一下category的刪除:
@Test
public void whenDeletingCategories_thenBooksShouldAlsoBeDeleted() {
categoryRepository.deleteAll();
assertThat(bookRepository.count()).isEqualTo(0);
assertThat(categoryRepository.count()).isEqualTo(0);
}
再看一下book的刪除:
@Test
public void whenDeletingBooks_thenCategoriesShouldAlsoBeDeleted() {
bookRepository.deleteAll();
assertThat(bookRepository.count()).isEqualTo(0);
assertThat(categoryRepository.count()).isEqualTo(1);
}
因為我們只在Category中指定了cascade = CascadeType.ALL, 所以刪除category的時候可以刪除相關聯的Book,但是刪除Book的時候不會刪除相關聯的category。
本文的例子可以參考https://github.com/ddean2009/learn-springboot2/tree/master/springboot-jpa-relation
更多教程請參考 flydean的博客