JPA的多對多映射

來源:互聯網
上載者:User

  實體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@GeneratedValueprivate 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@GeneratedValueprivate 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;@Beforepublic void before() {//根據在persistence.xml中配置的persistence-unit name 建立EntityManagerFactoryemf = Persistence.createEntityManagerFactory("myJPA");}@Afterpublic void after() {//關閉EntityManagerFactoryif(null != emf) {emf.close();}}/** * 建立玩家和遊戲 */@Testpublic void testSavePlayerAndGame() {EntityManager em = emf.createEntityManager();em.getTransaction().begin();//因為Player和Game之間沒有級聯儲存的關係,所以Playe和Game要分別儲存Player player = new Player();player.setName("西門吹雪");//儲存Playerem.persist(player);Game game = new Game();game.setName("大菠蘿3");//儲存gameem.persist(game);em.getTransaction().commit();em.close();}/** * 給玩家添加遊戲 */@Testpublic 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();}/** * 玩家刪除遊戲 */@Testpublic 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();}}

  產生的關聯表結構如下:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.