Spring-Data-JPA 定义实体类关系:多对多(增删改查)

Spring-Data-JPA 关系描述(多对多)    

        实体Book:书籍。

  实体Author:作者。

  书籍和作者是多对多的关系。一本书籍可以由很多的作者编写,一个作者也可以编写写很多本书。

  JPA中使用@ManyToMany来注解多对多的关系,由一个关联表来维护。这个关联表的表名默认是:主表名+下划线+从表名。(主表是指关系维护端对应的表,从表指关系被维护端对应的表)。这个关联表只有两个外键字段,分别指向主表ID和从表ID。字段的名称默认为:主表名+下划线+主表中的主键列名,从表名+下划线+从表中的主键列名。

 

  需要注意的:

  1、多对多关系中一般不设置级联保存、级联删除、级联更新等操作。

  2、可以随意指定一方为关系维护端,在这个例子中,我指定Book为关系维护端,所以生成的关联表名称为: book_author,关联表的字段为:book_id和author_id。

  3、多对多关系的绑定由关系维护端来完成,即由Book.setAuthors(authors)来绑定多对多的关系。关系被维护端不能绑定关系,即Author不能绑定关系。

  4、多对多关系的解除由关系维护端来完成,即由Book.getAuthors.remove(author)来解除多对多的关系。关系被维护端不能解除关系,即Author不能解除关系。

  5、如果Book和Author已经绑定了多对多的关系,那么不能直接删除Author,需要由Book解除关系后,才能删除Author。但是可以直接删除Book,因为Book是关系维护端,删除Book时,会先解除Book和Author的关系,再删除Author。

Spring-Data-JPA 源码

实体对象和Dao层

package com.zzg.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Entity
@Table(name="book")
public class Book implements Serializable {
	@Id
    @GeneratedValue
    private Long id;
	
	@Column(name="name")
    private String name;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "book_author", joinColumns = {
            @JoinColumn(name = "book_id", referencedColumnName = "id")}, inverseJoinColumns = {
            @JoinColumn(name = "author_id", referencedColumnName = "id")})
    private Set authors;

    public Book() {
        super();
    }

    public Book(String name) {
        super();
        this.name = name;
        this.authors = new HashSet<>();
    }

    public Book(String name, Set authors) {
        super();
        this.name = name;
        this.authors = authors;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set getAuthors() {
        return authors;
    }

    public void setAuthors(Set authors) {
        this.authors = authors;
    }

    @Override
    public String toString() {
        return String.format("Book [id=%s, name=%s, authors=%s]", id, name, authors);
    }
}
package com.zzg.entity;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Entity
@Table(name="author")
public class Author implements Serializable {
	@Id
    @GeneratedValue
    private Long id;

	@Column(name="name")
    private String name;

    @ManyToMany(mappedBy = "authors")
    private Set books;

    public Author() {
        super();
    }

    public Author(String name) {
        super();
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set getBooks() {
        return books;
    }

    public void setBooks(Set books) {
        this.books = books;
    }

    @Override
    public String toString() {
        return String.format("Author [id=%s, name=%s, books=%s]", id, name, books);
    }
}
package com.zzg.entity.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import com.zzg.entity.Author;

public interface AuthorRepository extends JpaRepository {

}
package com.zzg.entity.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import com.zzg.entity.Book;

public interface BookRepository extends JpaRepository {

}

 功能测试(test)定义:

package com.zzg.test;

import java.util.Arrays;
import java.util.Set;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.zzg.entity.Author;
import com.zzg.entity.Book;
import com.zzg.entity.dao.AuthorRepository;
import com.zzg.entity.dao.BookRepository;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ManyToManyTest {

	
	@Autowired
	private AuthorRepository authorRepository;
	
	@Autowired
	private BookRepository bookRepository;
	
	@Test
	public void insertManyToMany() {
		
		Author lewis = new Author("Lewis");
        Author mark = new Author("Mark");
        Author peter = new Author("Peter");

        Book spring = new Book("Spring in Action");
        spring.getAuthors().addAll(Arrays.asList(lewis, mark));

        Book springboot = new Book("Spring Boot in Action");
        springboot.getAuthors().addAll(Arrays.asList(lewis, peter));

        bookRepository.save(Arrays.asList(spring, springboot));
		
	}
	
	@Test
	public void selectManyToMany() {
		Book book = bookRepository.findOne(1L);
		System.out.println(book.toString());
		
		book.getAuthors().stream().forEach(item->{
			System.out.println(item.toString());
		});
		
		
	}
	
	@Test
	public void updateManyToMany() {
		// 移除目标数据
		Author author = authorRepository.findOne(1L);
		// 查询指定数据
		Book book = bookRepository.findOne(1L);
		System.out.println(book.toString());
		// 数据移除
		book.getAuthors().add(new Author("zzg"));
		// 数据保存
		bookRepository.save(book);
		
		
	}
	
	@Test
	public void deleteManyToMany() {
		bookRepository.delete(1L);
	}


}

效果截图:

新增

Spring-Data-JPA 定义实体类关系:多对多(增删改查)_第1张图片

修改

Spring-Data-JPA 定义实体类关系:多对多(增删改查)_第2张图片

删除

Spring-Data-JPA 定义实体类关系:多对多(增删改查)_第3张图片

查询

Spring-Data-JPA 定义实体类关系:多对多(增删改查)_第4张图片

建库脚本:

CREATE TABLE IF NOT EXISTS `author` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;


-- 导出  表 oasys.book 结构
CREATE TABLE IF NOT EXISTS `book` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;



-- 导出  表 oasys.book_author 结构
CREATE TABLE IF NOT EXISTS `book_author` (
  `book_id` bigint(10) NOT NULL,
  `author_id` bigint(10) NOT NULL,
  KEY `author_id` (`author_id`),
  KEY `book_id` (`book_id`),
  CONSTRAINT `author_id` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`),
  CONSTRAINT `book_id` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

 

你可能感兴趣的:(spring,Data,JPA)