`

JPA的多对多映射

    博客分类:
  • JPA
jpa 
阅读更多
  实体Player:玩家。
  实体Game:游戏。
  玩家和游戏是多对多的关系。一个玩家可以玩很多的游戏,一个游戏也可以被很多玩家玩。
  JPA中使用@ManyToMany来注解多对多的关系,由一个关联表来维护。这个关联表的表名默认是:主表名+下划线+从表名。(主表是指关系维护端对应的表,从表指关系被维护端对应的表)。这个关联表只有两个外键字段,分别指向主表ID和从表ID。字段的名称默认为:主表名+下划线+主表中的主键列名,从表名+下划线+从表中的主键列名。

  需要注意的:
  1、多对多关系中一般不设置级联保存、级联删除、级联更新等操作。
  2、可以随意指定一方为关系维护端,在这个例子中,我指定Player为关系维护端,所以生成的关联表名称为: player_game,关联表的字段为:player_id和game_id。
  3、多对多关系的绑定由关系维护端来完成,即由Player.setGames(games)来绑定多对多的关系。关系被维护端不能绑定关系,即Game不能绑定关系。
  4、多对多关系的解除由关系维护端来完成,即由Player.getGames().remove(game)来解除多对多的关系。关系被维护端不能解除关系,即Game不能解除关系。
  5、如果Player和Game已经绑定了多对多的关系,那么不能直接删除Game,需要由Player解除关系后,才能删除Game。但是可以直接删除Player,因为Player是关系维护端,删除Player时,会先解除Player和Game的关系,再删除Player。
  Player.java如下:

package com.cndatacom.jpa.entity;

import java.util.HashSet;
import java.util.Set;

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;


/**
* 玩家
* @author Luxh
*/
@Entity
@Table(name="player")
public class Player {
    
    @Id
    @GeneratedValue
    private Long id;
    
    /**玩家姓名*/
    @Column(length=32)
    private String name;
    
    
    /**玩家玩的游戏*/
    @ManyToMany
    @JoinTable(name="player_game",joinColumns=@JoinColumn(name="player_id"),
                    inverseJoinColumns=@JoinColumn(name="game_id"))
    //关系维护端,负责多对多关系的绑定和解除
    //@JoinTable注解的name属性指定关联表的名字,joinColumns指定外键的名字,关联到关系维护端(Player)
    //inverseJoinColumns指定外键的名字,要关联的关系被维护端(Game)
    //其实可以不使用@JoinTable注解,默认生成的关联表名称为主表表名+下划线+从表表名,
    //即表名为player_game
    //关联到主表的外键名:主表名+下划线+主表中的主键列名,即player_id
    //关联到从表的外键名:主表中用于关联的属性名+下划线+从表的主键列名,即game_id
    //主表就是关系维护端对应的表,从表就是关系被维护端对应的表
    private Set<Game> games = new HashSet<Game>();


    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<Game> getGames() {
        return games;
    }


    public void setGames(Set<Game> games) {
        this.games = games;
    }
    
}
  Game.java如下:
  

package com.cndatacom.jpa.entity;

import java.util.HashSet;
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;


/**
* 游戏
* @author Luxh
*/

@Entity
@Table(name="game")
public class Game {
    
    @Id
    @GeneratedValue
    private Long id;
    
    /**游戏名称*/
    @Column(length=32)
    private String name;
    
    /**游戏拥有的玩家*/
    @ManyToMany(mappedBy="games")
    //只需要设置mappedBy="games"表明Game实体是关系被维护端就可以了
    //级联保存、级联删除等之类的属性在多对多关系中是不需要设置
    //不能说删了游戏,把玩家也删掉,玩家还可以玩其他的游戏
    private Set<Player> players = new HashSet<Player>();

    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<Player> getPlayers() {
        return players;
    }

    public void setPlayers(Set<Player> players) {
        this.players = players;
    }
    
    
}
  简单的测试如下:
  

package com.cndatacom.jpa.test;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.cndatacom.jpa.entity.Game;
import com.cndatacom.jpa.entity.Player;

public class TestManyToMany {
    
EntityManagerFactory emf = null;
    
    @Before
    public void before() {
        //根据在persistence.xml中配置的persistence-unit name 创建EntityManagerFactory
        emf = Persistence.createEntityManagerFactory("myJPA");
    }
    
    @After
    public void after() {
        //关闭EntityManagerFactory
        if(null != emf) {
            emf.close();
        }
    }
    
    /**
     * 创建玩家和游戏
     */
    @Test
    public void testSavePlayerAndGame() {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        //因为Player和Game之间没有级联保存的关系,所以Playe和Game要分别保存
        
        Player player = new Player();
        player.setName("西门吹雪");
        //保存Player
        em.persist(player);
        
        Game game = new Game();
        game.setName("大菠萝3");
        //保存game
        em.persist(game);
        
        em.getTransaction().commit();
        em.close();
    }
    
    /**
     * 给玩家添加游戏
     */
    @Test
    public void testAddGameToPlayer() {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        //找出ID为1的玩家
        Player player = em.find(Player.class, 1L);
        //找出ID为1的游戏
        Game game = em.find(Game.class, 1L);
        
        Set<Game> games = new HashSet<Game>();
        games.add(game);
        
        //因为Player是关系的维护端,所以必须由Player来添加关系
        player.setGames(games);
        
        em.getTransaction().commit();
        em.close();
    }
    
    /**
     * 玩家删除游戏
     */
    @Test
    public void testRemoveGameFormPlayer() {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        //找出ID为1的玩家
        Player player = em.find(Player.class, 1L);
        //找出ID为1的游戏
        Game game = em.find(Game.class, 1L);
        
        //因为Player是关系维护端,所以关系的解除由Player来完成
        player.getGames().remove(game);
        em.getTransaction().commit();
        em.close();
    }
}
分享到:
评论

相关推荐

    自己做的一个jpa多对多映射的一个例子

    刚学完了hibernate和ejb,自己又自学了下jpa,看了黎活明老师的视频,自己做了个多对多的例子,希望可以对你学习有所帮助,有心人可以联系我QQ770256061!

    JPA一对一,一对多,多对多关系映射

    本篇将深入探讨JPA中的一对一(OneToOne)、一对多(OneToMany)以及多对多(ManyToMany)关系映射。 ### 1. JPA 一对一(OneToOne)关系映射 **概念**:一对一关系意味着两个实体之间存在唯一的关联,一个实体...

    JPA映射关系详解javax JPA JPA映射关系 JPA映射

    ### JPA映射关系详解 Java Persistence API (JPA) 是一种用于管理关系型数据库中的数据的标准 Java 技术。JPA 提供了一种对象关系映射 (ORM) 方法来处理数据库,允许开发者以面向对象的方式操作数据库。本文将详细...

    JPA映射关系,多种映射关系的图解

    JPA映射关系,多种映射关系的图解,适合EJB初学者,对JPA映射关系的了解.

    JPA多对多Demo

    **JPA多对多关联关系详解** 在Java开发中,对象关系映射(ORM)框架如JPA(Java Persistence API)极大地简化了数据库操作。JPA是Java EE的一部分,为开发者提供了一种标准的方式来处理数据库操作,使得我们可以用...

    jpa的实体映射关系7种

    在单向多对多关系中,一个实体可以关联多个其他实体,而这些实体并不知道这个关联。使用`@ManyToMany`注解,关联表通常由JPA自动创建,除非自定义了`@JoinTable`。 7. **双向多对多**: 双向多对多是最复杂的关系...

    使用jpa映射关联和继承

    3. **多对一(ManyToOne)映射**:多个子对象对应一个父对象,与一对一相反,通过`@ManyToOne`注解实现。同样可设置`fetch`策略和`@JoinColumn`来定义外键。 4. **多对多(ManyToMany)映射**:一个实体可以与多个...

    05_传智播客JPA详解_日期_枚举等字段类型的JPA映射

    JPA支持一对一、一对多、多对一和多对多的关系映射,通过`@OneToOne`、`@OneToMany`、`@ManyToOne`和`@ManyToMany`注解实现。关联关系可以是懒加载或即时加载,通过`fetch`属性配置。 6. **查询语言JPQL**: JPA...

    05_JPA详解_日期_枚举等字段类型的JPA映射.zip

    JPA提供了多种关系映射方式,如一对一(@OneToOne)、一对多(@OneToMany)、多对一(@ManyToOne)和多对多(@ManyToMany)。这些关系可以通过`@JoinColumn`和`@JoinTable`注解进行配置。 ### 7. 查询语言 JPA提供...

    JPA中的多对多双向关联实体定义与注解设置

    在Java Persistence API (JPA) 中,多对多(ManyToMany)关系是表示两个实体之间复杂关联的一种方式。这种关联允许一个实体实例可以与多个其他实体实例相关联,反之亦然。例如,一个学生可以选修多门课程,一门课程...

    JPA视频教程_使用jpa映射单个实体对象

    4. **关系映射(Relationship Mapping)**: JPA也支持处理对象之间的关系,如一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)和多对多(ManyToMany)。例如,一个User可能有多个Order,可以这样映射...

    JPA实体映射对时间字段的处理

    ### JPA实体映射对时间字段的处理 在Java持久化框架中,JPA(Java Persistence API)是一种广泛采用的标准,用于管理关系型数据库中的对象/关系映射。本文将详细探讨在使用JPA进行实体映射时如何处理时间字段,并...

    JPA一对多映射关系解析

    为了方便广大开发朋友的需要特整理一下有关jpa映射关系,希望可以帮助到一些朋友。

    Hibernate annotation JPA 一对多,多对多

    在本主题中,我们将深入探讨使用Hibernate注解来实现JPA的一对多、多对多和多对一的关系映射。 1. **一对多关系**: 在现实世界中,一个老师可以教多个学生,或者一个班级可以包含多个学生,这就是典型的一对多...

    13_jpa多对多双向关联实体定义与注解

    "13_传智播客JPA详解"系列教程涵盖了JPA的诸多方面,而"13_传智播客JPA详解_JPA中的多对多双向关联实体定义与注解设置"这一部分则专门聚焦于多对多关联的实践。 在关系型数据库中,多对多关联是最为复杂的一种关系...

    JPA学习笔记-EJB-04JPA关联映射总结

    用户可以属于多个角色,每个角色可以有多个用户,并且角色与菜单之间存在多对多的关系,表示角色具有特定的操作权限,用户通过角色来获取这些权限。 在建模阶段,我们创建了如下的关系模型: - UxAdmin实体包含了...

    jpa映射关系详解[参照].pdf

    jpa映射关系详解[参照].pdf

    JPA-4 映射关联关系

    JPA 提供了多种方式来处理不同类型的关联关系,包括单向多对一、单向一对多、双向一对一、双向多对一和双向多对多。下面我们将详细探讨这些关联关系的实现方法。 1. **单向多对一关联关系(SingleManyToOne)** 在...

    JPA一对多和多对一关系

    在JPA中,实体间的关系映射是核心概念之一,其中一对多(OneToMany)和多对一(ManyToOne)是两种常见的关系类型。 ### 一对多关系(OneToMany) 在数据库中,一对多关系意味着一个表中的记录可以与另一个表中的多...

    14_传智播客JPA详解_JPA中的多对多双向关联的各项关系操作

    在JPA中,多对多(Many-to-Many)关联是一种常见的关系类型,适用于描述两个实体之间复杂的关系。本教程将深入探讨JPA中多对多双向关联的各个方面及其操作。 在数据库中,多对多关联意味着一个实体可以与多个其他...

Global site tag (gtag.js) - Google Analytics