乐趣区

ManyToMany中的mappedy

好长时间没有从零开始写项目,这次写软件工程的实验时,发现自己又对这个东西的概念模糊了,就复习了一下,并记录一下方便以后复习。

mappedy 总览

  • 只有 OneToOne,OneToMany,ManyToMany 上才有 mappedBy 属性,ManyToOne 不存在该属性;
  • mappedBy 标签一定是定义在被拥有方的,他指向拥有方;
  • mappedBy 的含义,应该理解为,拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以做到的;
  • mappedBy 跟 joinColumn/JoinTable 总是处于互斥的一方,可以理解为正是由于拥有方的关联被拥有方的字段存在,拥有方才拥有了被拥有方。mappedBy 这方定义 JoinColumn/JoinTable 总是失效的,不会建立对应的字段或者表。

查询了一段时间,得到了一个简单容易理解的解释

mappedBy 表示声明自己不是一对多的关系维护端,由对方来维护,是在一的一方进行声明的。mappedBy 的值应该为一的一方的表名。
例如:班级与学生,一个班级有多个学生。

 

但是这说的是一对多的关系,当然,多对多也可以理解为多个一对多嘛,好像也能解释通,但还是想了解的更准确一些。

在多对多中的作用

在 Stack Overflow 上找到一个和我问题相似的


翻译一下上面的解释:

如果关联是双向的,则一方必须是所有者,另一方必须是反向端(即在更新关联表中的关系值时将忽略它):
所以,具有 mappedby 属性的边是相反的边。没有 mappedby 属性的一方是所有者。
(mappedy 在 Foo 中)
所有者侧是 Hibernate 所查看的哪一个关联存在的方。因此,例如,如果在 Bar 的 foo 集合中添加 foo,hibernate 将在表中插入一个新行。相反,如果在 Foo 的 bar 集合中添加一个 bar,则数据库中不会修改任何内容。

尝试了对上述结论进行验证,但发现并无法验证,如此多的赞,可以肯定他的结论一定是正确的,只能说明自己理解的有问题或者测试方法有问题,代码如下

假设 Klass 和 Teacher 两个实体,他们的关系为多对多;

@Entity
public class Teacher  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    
    @ManyToMany(mappedBy = "teacherList")
    private List<Klass> klassList = new ArrayList<>();}

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
class TeacherRepositoryTest {

    @Autowired
    KlassRepository klassRepository;
    @Autowired
    TeacherRepository teacherRepository;

    @Test
    public void test() {
        
        // 新建两个 teacher
        Teacher teacher1 = new Teacher();
        Teacher teacher2 = new Teacher();
        teacher1 = teacherRepository.save(teacher1);
        teacher2 = teacherRepository.save(teacher2);

        // 新建一个 klass
        Klass klass1 = new Klass();
        klass1 = klassRepository.save(klass1);


        // 在 klassList 中中插入 teacher
        List<Teacher> teacherList = klass1.getTeacherList();
        teacherList.add(teacherRepository.findById(teacher1.getId()).get());

        klass1.setTeacherList(teacherList);
        klassRepository.save(klass1);

        Teacher teacher = teacherRepository.findById(teacher2.getId()).get();

        // 在 teacherList 中插入 klass
        List<Klass> klassList = teacher.getKlassList();
        klassList.add(klass1);
        teacher.setKlassList(klassList);

        // 使用断点查看 发现数据全都插进去了
        Teacher teacher3 = teacherRepository.findById(teacher.getId()).get();}
}

希望有大神能解答一下。

总结

前段时间看《on java 8》解答了自己很多在 java 中的疑惑,虽然对现在看到的部分又感到了困难,但总的来说 java 的知识比以前更加的系统了,也许 spring 的相关知识自己也应该找本书或教程来系统的学习一下了,总感觉现在的会的特别的散乱,很多方面都知道一点,但又不是特别清晰。

参考文章

@ManyToMany(mappedBy =“foo”)(Stack Overflow 的问题)
mappedBy 的具体使用及其含义

退出移动版