JPA 菜鳥教程 7 雙向多對多

雙向多對多的ddl語句

同單向多對多表的ddl語句一致

Student

package com.jege.jpa.many2many;

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

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

/**
 * @author JE哥
 * @email 1272434821@qq.com
 * @description:雙向:關(guān)系被維護端:不能操作中間表
 */
@Entity
@Table(name = "t_student")
public class Student {
  @Id
  @GeneratedValue
  private Long id;
  private String sname;
  @ManyToMany(mappedBy = "students")
  private Set<Teacher> teachers = new HashSet<Teacher>();

  public Student() {

  }

  public Student(String sname) {
    this.sname = sname;
  }

  public Long getId() {
    return id;
  }

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

  public String getSname() {
    return sname;
  }

  public void setSname(String sname) {
    this.sname = sname;
  }

  public Set<Teacher> getTeachers() {
    return teachers;
  }

  public void setTeachers(Set<Teacher> teachers) {
    this.teachers = teachers;
  }

  @Override
  public String toString() {
    return "Student [id=" + id + ", sname=" + sname + "]";
  }

}

Teacher

package com.jege.jpa.many2many;

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

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
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 JE哥
 * @email 1272434821@qq.com
 * @description:雙向:關(guān)系維護端:可以操作中間表
 */
@Entity
@Table(name = "t_teacher")
public class Teacher {
  @Id
  @GeneratedValue
  private Long id;
  private String tname;
  // @ManyToMany注釋表示Teacher是多對多關(guān)系的一端。
  // @JoinTable描述了多對多關(guān)系的數(shù)據(jù)表關(guān)系咖熟。name屬性指定中間表名稱,joinColumns定義中間表與Teacher表的外鍵關(guān)系。
  // 中間表Teacher_Student的Teacher_ID列是Teacher表的主鍵列對應(yīng)的外鍵列推溃,inverseJoinColumns屬性定義了中間表與另外一端(Student)的外鍵關(guān)系。
  @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
  @JoinTable(name = "t_teacher_student", joinColumns = { @JoinColumn(name = "teacher_id") }, inverseJoinColumns = {
      @JoinColumn(name = "student_id") })
  private Set<Student> students = new HashSet<Student>();

  public Teacher() {

  }

  public Teacher(String tname) {
    this.tname = tname;
  }

  public Long getId() {
    return id;
  }

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

  public String getTname() {
    return tname;
  }

  public void setTname(String tname) {
    this.tname = tname;
  }

  public Set<Student> getStudents() {
    return students;
  }

  public void setStudents(Set<Student> students) {
    this.students = students;
  }

  @Override
  public String toString() {
    return "Teacher [id=" + id + ", tname=" + tname + "]";
  }
}

Many2ManyTest

package com.jege.jpa.many2many;

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

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

/**
 * @author JE哥
 * @email 1272434821@qq.com
 * @description:雙向多對多Test
 */
public class Many2ManyTest {
  private static EntityManagerFactory entityManagerFactory = null;
  private EntityManager entityManager = null;

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    entityManagerFactory = Persistence.createEntityManagerFactory("com.jege.jpa");
  }

  @Before
  public void setUp() throws Exception {
    entityManager = entityManagerFactory.createEntityManager();
  }

  // t1老師教2個學(xué)生s1,s2
  // t2老師教3個學(xué)生s1,s2,s3
  // 總共10條insert
  @Test
  public void persist() throws Exception {
    entityManager.getTransaction().begin();

    Teacher t1 = new Teacher("t1");
    Teacher t2 = new Teacher("t2");

    Student s1 = new Student("s1");
    Student s2 = new Student("s2");
    Student s3 = new Student("s3");

    entityManager.persist(t1);
    entityManager.persist(t2);

    entityManager.persist(s1);
    entityManager.persist(s2);
    entityManager.persist(s3);// 全部發(fā)出5條insert單表

    // 添加中間表
    // t1老師教2個學(xué)生s1,s2
    // t2老師教3個學(xué)生s1,s2,s3
    t1.getStudents().add(s1);
    t1.getStudents().add(s2);

    t2.getStudents().add(s1);
    t2.getStudents().add(s2);
    t2.getStudents().add(s3);

    entityManager.getTransaction().commit();// 發(fā)出5條insert中間表
    entityManager.close();
  }

  // t1老師教2個學(xué)生s1,s2
  // 修改為 教2個學(xué)生s1,s3:先刪除在添加
  @Test
  public void update() throws Exception {
    persist();

    entityManager.getTransaction().begin();

    Teacher t1 = entityManager.find(Teacher.class, 1L);
    Student s2 = entityManager.find(Student.class, 2L);
    Student s3 = entityManager.find(Student.class, 3L);
    // 刪除
    t1.getStudents().remove(s2);
    // 添加
    t1.getStudents().add(s3);

    entityManager.getTransaction().commit();
  }

  // 刪除t1的教的所有學(xué)生
  @Test
  public void delete() throws Exception {
    persist();

    entityManager.getTransaction().begin();

    Teacher t1 = entityManager.find(Teacher.class, 1L);
    t1.getStudents().clear();

    entityManager.getTransaction().commit();
  }

  // insert 3條缎脾,單表插入,中間表無反應(yīng)
  // 因為Student是關(guān)系被維護端:不能操作中間表
  @Test
  public void persist2() throws Exception {
    Teacher teacher = new Teacher("t1");

    Student student1 = new Student("s1");
    Student student2 = new Student("s2");

    student1.getTeachers().add(teacher);// 插入中間表
    student2.getTeachers().add(teacher);

    entityManager.getTransaction().begin();
    entityManager.persist(teacher);
    entityManager.persist(student1);
    entityManager.persist(student2);
    entityManager.getTransaction().commit();
  }

  @Test
  public void find() throws Exception {
    persist();
    
    entityManager = entityManagerFactory.createEntityManager();
    Teacher teacher = entityManager.find(Teacher.class, 1L);
    System.out.println(teacher.getTname());
    System.out.println("------------------");
    System.out.println(teacher.getStudents());

  }

  @Test
  public void find2() throws Exception {
    persist();
    
    entityManager = entityManagerFactory.createEntityManager();
    Student student = entityManager.find(Student.class, 1L);
    System.out.println(student.getSname());
    System.out.println("------------------");
    System.out.println(student.getTeachers());

  }

  @After
  public void tearDown() throws Exception {
    if (entityManager != null && entityManager.isOpen())
      entityManager.close();
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    if (entityManagerFactory != null && entityManagerFactory.isOpen())
      entityManagerFactory.close();
  }
}

其他關(guān)聯(lián)項目

源碼地址

https://github.com/je-ge/jpa

如果覺得我的文章或者代碼對您有幫助,可以請我喝杯咖啡深滚。
**您的支持將鼓勵我繼續(xù)創(chuàng)作!謝謝! **

微信打賞
微信打賞

支付寶打賞
支付寶打賞

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仪缸,一起剝皮案震驚了整個濱河市贵涵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖宾茂,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓷马,死亡現(xiàn)場離奇詭異,居然都是意外死亡跨晴,警方通過查閱死者的電腦和手機欧聘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來端盆,“玉大人怀骤,你說我怎么就攤上這事』烂睿” “怎么了蒋伦?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長焚鹊。 經(jīng)常有香客問我痕届,道長,這世上最難降的妖魔是什么寺旺? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任爷抓,我火速辦了婚禮,結(jié)果婚禮上阻塑,老公的妹妹穿的比我還像新娘蓝撇。我一直安慰自己,他們只是感情好陈莽,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布渤昌。 她就那樣靜靜地躺著,像睡著了一般走搁。 火紅的嫁衣襯著肌膚如雪独柑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天私植,我揣著相機與錄音忌栅,去河邊找鬼。 笑死曲稼,一個胖子當著我的面吹牛索绪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贫悄,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼瑞驱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了窄坦?” 一聲冷哼從身側(cè)響起唤反,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凳寺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后彤侍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挥转,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡们妥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年晓淀,在試婚紗的時候發(fā)現(xiàn)自己被綠了线罕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片父泳。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡般哼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惠窄,到底是詐尸還是另有隱情蒸眠,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布杆融,位于F島的核電站楞卡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏脾歇。R本人自食惡果不足惜蒋腮,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望藕各。 院中可真熱鬧池摧,春花似錦、人聲如沸激况。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乌逐。三九已至竭讳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浙踢,已是汗流浹背绢慢。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留洛波,地道東北人胰舆。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像奋岁,于是被迫代替她去往敵國和親思瘟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 聯(lián)合子類策略 這種情況下子類的字段被映射到各自的表中闻伶,這些字段包括父類中的字段滨攻,并執(zhí)行一個join操作來實例化子類...
    JeGe閱讀 1,563評論 0 1
  • “七八十年代的愛情,一把紙傘,幾封情書光绕,不夠直白女嘲,委婉相訴也能靦腆牽手,一面之緣也可以白頭到老"诞帐。 一直以來都很喜...
    青禾Summer閱讀 216評論 0 0
  • 由于各個國家都都對鋼格板欣尼,鋼格柵,格柵板感興趣下面是科邁鋼格板對網(wǎng)站上鋼格板的一些翻譯停蕉,這些翻譯不是特別準確 英文...
    大事爆料閱讀 2,105評論 0 0
  • 雖然不為成吉思汗而來愕鼓,卻也和這段彪悍的歷史巧遇。大山深處慧起,我們看到了水草豐美的一片腹地菇晃,三面還山,易守難攻蚓挤,當年鐵...
    心如美玉閱讀 136評論 0 1
  • “趣”是一個內(nèi)涵飽滿灿意、意味深長的字眼兒估灿。人人都喜歡“有趣”的人,做“有趣”的事兒缤剧。前幾天馅袁,和一個資深的語文老師聊天...
    彩虹mm閱讀 582評論 1 6