hibernate ——关联关系
1、一对一单向外键关联
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <!-- <property name="connection.driver_class">org.hsqldb.jdbcDriver</property> <property name="connection.url">jdbc:hsqldb:hsql://localhost/TestDB</property> --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8</property> <property name="connection.username">root</property> <property name="connection.password"></property> <property name="hbm2ddl.auto">update</property> <!-- SQL dialect --> <property name="dialect"> org.hibernate.dialect.MySQL5InnoDBDialect </property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping class="com.pt.hibernate.Husband" /> <mapping class="com.pt.hibernate.Wife" /> </session-factory> </hibernate-configuration>
package com.pt.hibernate; import java.util.Date; import javax.annotation.Generated; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; @Entity public class Husband { int id; String name; Date bornTime; Wife myWife ; @OneToOne @JoinColumn(name="wifiId") //指定外键字段名 public Wife getMyWife() { return myWife; } public void setMyWife(Wife myWife) { this.myWife = myWife; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBornTime() { return bornTime; } public void setBornTime(Date bornTime) { this.bornTime = bornTime; } }
package com.pt.hibernate; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Wife { int id; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBornTime() { return bornTime; } public void setBornTime(Date bornTime) { this.bornTime = bornTime; } String name; Date bornTime; }
import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Test { public static void main(String[] arges){ Configuration cfg = new Configuration(); SessionFactory factory = cfg.configure().buildSessionFactory(); } }
2、一对一双向外键关联
两个相关联的实体类都写上@OneToOne即可,如果指定OneToOne的(mappedBy="")属性,这样就不会在两个表中都保留对方的ID,只会在其中一个表中保留对方的ID。只要有双向关联,该属性必设置。
package com.pt.hibernate; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; @Entity public class Wife { int id; String name; Date bornTime; Husband myHusband ; @OneToOne(mappedBy="myWife") public Husband getMyHusband() { return myHusband; } public void setMyHusband(Husband myHusband) { this.myHusband = myHusband; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBornTime() { return bornTime; } public void setBornTime(Date bornTime) { this.bornTime = bornTime; } }
3、多对一单向外键关联
多对一,数据库中的表现是在多的一方记录一的一方的ID,添加Son类,同时在配置文件中配置,Son类如下:
package com.pt.hibernate; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; @Entity public class Son { int id; String name; Husband myFather; @ManyToOne @JoinColumn(name="fatherId") public Husband getMyFather() { return myFather; } public void setMyFather(Husband myFather) { this.myFather = myFather; } @Id public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
4、多对一双向外键关联
在3、的基础上,修改Husband类,如下:
package com.pt.hibernate; import java.util.Date; import java.util.Set; import javax.annotation.Generated; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.OneToOne; @Entity public class Husband { int id; String name; Date bornTime; Wife myWife ; Set<Son> sons; @OneToMany(mappedBy="myFather") public Set<Son> getSons() { return sons; } public void setSons(Set<Son> sons) { this.sons = sons; } @OneToOne @JoinColumn(name="wifiId") //指定外键字段名 public Wife getMyWife() { return myWife; } public void setMyWife(Wife myWife) { this.myWife = myWife; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBornTime() { return bornTime; } public void setBornTime(Date bornTime) { this.bornTime = bornTime; } }
5、一对一单向主键关联
修改husband和wife类,这时候husband依赖于wife,如果没有wife对应的ID,则husband插不进去记录!
package com.pt.hibernate; import java.util.Date; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; @Entity public class Husband { int id; String name; Date bornTime; Wife myWife ; Set<Son> sons; @OneToMany(mappedBy="myFather") public Set<Son> getSons() { return sons; } public void setSons(Set<Son> sons) { this.sons = sons; } @OneToOne(optional=false) //optional表示该属性是否可以为null 默认为true //@JoinColumn(name="wifiId") //指定外键字段名 @PrimaryKeyJoinColumn public Wife getMyWife() { return myWife; } public void setMyWife(Wife myWife) { this.myWife = myWife; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBornTime() { return bornTime; } public void setBornTime(Date bornTime) { this.bornTime = bornTime; } }
package com.pt.hibernate; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; @Entity public class Wife { int id; String name; Date bornTime; // Husband myHusband ; // @OneToOne(mappedBy="myWife") // public Husband getMyHusband() { // return myHusband; // } // public void setMyHusband(Husband myHusband) { // this.myHusband = myHusband; // } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBornTime() { return bornTime; } public void setBornTime(Date bornTime) { this.bornTime = bornTime; } }
6、一对一双向向主键关联
修改Wife类
package com.pt.hibernate; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; @Entity public class Wife { int id; String name; Date bornTime; Husband myHusband ; @OneToOne(mappedBy="myWife") public Husband getMyHusband() { return myHusband; } public void setMyHusband(Husband myHusband) { this.myHusband = myHusband; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBornTime() { return bornTime; } public void setBornTime(Date bornTime) { this.bornTime = bornTime; } }
7、多对多单向关联
在数据库中,针对多对多的关系,如:学生与老师的关系,一般都是有一张中间表维护!同时,需要建立一张中间表对应的类~~
1 package com.pt.hibernate; 2 3 import java.util.Set; 4 5 import javax.persistence.CascadeType; 6 import javax.persistence.Entity; 7 import javax.persistence.Id; 8 import javax.persistence.IdClass; 9 import javax.persistence.JoinColumn; 10 import javax.persistence.JoinTable; 11 import javax.persistence.ManyToMany; 12 13 import org.hibernate.engine.internal.Cascade; 14 15 @Entity 16 @IdClass(value=UnionId.class) 17 public class Student { 18 String schoolName; 19 int id; 20 String stuName; 21 Set<Teacher> myTeachers; 22 @ManyToMany(cascade=CascadeType.ALL) 23 @JoinTable( 24 name="teacher_stu", 25 joinColumns={//当前类的ID 26 @JoinColumn(name="stu_id"), 27 @JoinColumn(name="school_id") 28 }, 29 inverseJoinColumns={//与当前类关联的类的ID 30 @JoinColumn(name="teacher_id"), 31 } 32 33 ) 34 public Set<Teacher> getMyTeachers() { 35 return myTeachers; 36 } 37 public void setMyTeachers(Set<Teacher> myTeachers) { 38 this.myTeachers = myTeachers; 39 } 40 public String getStuName() { 41 return stuName; 42 } 43 public void setStuName(String stuName) { 44 this.stuName = stuName; 45 } 46 @Id 47 public String getSchoolName() { 48 return schoolName; 49 } 50 public void setSchoolName(String schoolName) { 51 this.schoolName = schoolName; 52 } 53 @Id 54 public int getId() { 55 return id; 56 } 57 public void setId(int id) { 58 this.id = id; 59 } 60 61 }
1 package com.pt.hibernate; 2 3 import java.util.Set; 4 5 import javax.persistence.CascadeType; 6 import javax.persistence.Entity; 7 import javax.persistence.GeneratedValue; 8 import javax.persistence.Id; 9 import javax.persistence.ManyToMany; 10 11 import org.hibernate.engine.internal.Cascade; 12 13 @Entity 14 public class Teacher { 15 int id; 16 String name; 17 String courese; //教授课程 18 Set<Student> myStudents; 19 @ManyToMany(mappedBy="myTeachers",cascade=CascadeType.ALL) 20 public Set<Student> getMyStudents() { 21 return myStudents; 22 } 23 public void setMyStudents(Set<Student> myStudents) { 24 this.myStudents = myStudents; 25 } 26 @Id 27 @GeneratedValue 28 public int getId() { 29 return id; 30 } 31 public void setId(int id) { 32 this.id = id; 33 } 34 public String getName() { 35 return name; 36 } 37 public void setName(String name) { 38 this.name = name; 39 } 40 public String getCourese() { 41 return courese; 42 } 43 public void setCourese(String courese) { 44 this.courese = courese; 45 } 46 47 }
生成的表结构如下:
CREATE TABLE `student` ( `id` int(11) NOT NULL, `schoolName` varchar(255) NOT NULL, `stuName` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`,`schoolName`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `teacher` ( `id` int(11) NOT NULL, `courese` varchar(255) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `teacher_stu` ( `stu_id` int(11) NOT NULL, `school_id` varchar(255) NOT NULL, `teacher_id` int(11) NOT NULL, PRIMARY KEY (`stu_id`,`school_id`,`teacher_id`), KEY `FK3913g7i2hhmoifd6umlvicvck` (`teacher_id`), CONSTRAINT `FK3913g7i2hhmoifd6umlvicvck` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`), CONSTRAINT `FKiv4krpyoes8tqxfy89uewaimm` FOREIGN KEY (`stu_id`, `school_id`) REFERENCES `student` (`id`, `schoolName`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
8、多对多双向关联
在7、基础上,修改Teacher.java类
package com.pt.hibernate; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; @Entity public class Teacher { int id; String name; String courese; //教授课程 Set<Student> myStudents; @ManyToMany(mappedBy="myTeachers") public Set<Student> getMyStudents() { return myStudents; } public void setMyStudents(Set<Student> myStudents) { this.myStudents = myStudents; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCourese() { return courese; } public void setCourese(String courese) { this.courese = courese; } }
总结:1、双向关联,必用mappedBy属性
2、单向与双向关联,对于数据库结构是没有区别的,区别在于程序中是否可以通过一方寻找另一方;
如:A与B单向关联,只可以通过A找B,通过B找不到A,
双向关联,则可以通过A找B,也可以通过B找A;
多对多补充:
1 package com.pt.hibernate; 2 3 import javax.persistence.CascadeType; 4 import javax.persistence.Entity; 5 import javax.persistence.GeneratedValue; 6 import javax.persistence.Id; 7 import javax.persistence.JoinColumn; 8 import javax.persistence.JoinColumns; 9 import javax.persistence.ManyToOne; 10 import javax.persistence.Table; 11 12 @Entity 13 @Table(name="teacher_stu") 14 public class Teacher_stu { 15 int id; 16 Student student; 17 18 Teacher teacher; 19 public Teacher_stu() { 20 } 21 22 public Teacher_stu(int in_id,Student in_student,Teacher in_teacher) { 23 this.id = in_id; 24 this.student = in_student; 25 this.teacher = in_teacher; 26 } 27 28 29 @ManyToOne 30 //最好指定列名 别用默认的 31 @JoinColumns({ 32 @JoinColumn(name="stu_id"), 33 @JoinColumn(name="school_id") 34 } 35 ) 36 public Student getStudent() { 37 return student; 38 } 39 public void setStudent(Student student) { 40 this.student = student; 41 } 42 @Id 43 @GeneratedValue 44 public int getId() { 45 return id; 46 } 47 public void setId(int id) { 48 this.id = id; 49 } 50 @ManyToOne 51 @JoinColumn(name="teacher_id") 52 public Teacher getTeacher() { 53 return teacher; 54 } 55 public void setTeacher(Teacher teacher) { 56 this.teacher = teacher; 57 } 58 59 }
1 package com.pt.hibernate; 2 3 import java.io.Serializable; 4 import java.util.Set; 5 6 import javax.persistence.CascadeType; 7 import javax.persistence.Entity; 8 import javax.persistence.GeneratedValue; 9 import javax.persistence.Id; 10 import javax.persistence.ManyToMany; 11 import javax.persistence.OneToMany; 12 13 import org.hibernate.engine.internal.Cascade; 14 15 @Entity 16 public class Teacher { 17 int id; 18 String name; 19 String courese; //教授课程 20 Set<Student> myStudents; 21 Set<Teacher_stu> t_s; 22 23 public Teacher() { 24 } 25 26 public Teacher(int in_id,String in_name) { 27 this.id = in_id; 28 this.name = in_name; 29 } 30 31 32 @OneToMany(mappedBy="teacher") 33 public Set<Teacher_stu> getT_s() { 34 return t_s; 35 } 36 public void setT_s(Set<Teacher_stu> t_s) { 37 this.t_s = t_s; 38 } 39 40 @ManyToMany(mappedBy="myTeachers") 41 public Set<Student> getMyStudents() { 42 return myStudents; 43 } 44 public void setMyStudents(Set<Student> myStudents) { 45 this.myStudents = myStudents; 46 } 47 @Id 48 //@GeneratedValue 49 public int getId() { 50 return id; 51 } 52 public void setId(int id) { 53 this.id = id; 54 } 55 public String getName() { 56 return name; 57 } 58 public void setName(String name) { 59 this.name = name; 60 } 61 public String getCourese() { 62 return courese; 63 } 64 public void setCourese(String courese) { 65 this.courese = courese; 66 } 67 68 }
1 package com.pt.hibernate; 2 3 import java.io.Serializable; 4 import java.util.HashSet; 5 import java.util.Set; 6 7 import javax.persistence.CascadeType; 8 import javax.persistence.Entity; 9 import javax.persistence.Id; 10 import javax.persistence.IdClass; 11 import javax.persistence.JoinColumn; 12 import javax.persistence.JoinTable; 13 import javax.persistence.ManyToMany; 14 import javax.persistence.OneToMany; 15 16 import org.hibernate.engine.internal.Cascade; 17 18 @Entity 19 @IdClass(value=UnionId.class) 20 public class Student implements Serializable{ 21 String schoolName; 22 int id; 23 String stuName; 24 Set<Teacher> myTeachers; 25 Set<Teacher_stu> t_s; 26 27 public Student() { 28 myTeachers = new HashSet<Teacher>(); 29 t_s = new HashSet<Teacher_stu>(); 30 } 31 32 public Student(int in_id,String in_stuName,String in_schoolName) { 33 this.id = in_id; 34 this.stuName = in_stuName; 35 this.schoolName = in_schoolName; 36 myTeachers = new HashSet<Teacher>(); 37 t_s = new HashSet<Teacher_stu>(); 38 } 39 40 @OneToMany(mappedBy="student") 41 public Set<Teacher_stu> getT_s() { 42 return t_s; 43 } 44 public void setT_s(Set<Teacher_stu> t_s) { 45 this.t_s = t_s; 46 } 47 48 @ManyToMany(cascade=CascadeType.ALL) 49 @JoinTable( 50 name="teacher_stu", 51 joinColumns={//当前类的ID 52 @JoinColumn(name="stu_id"), 53 @JoinColumn(name="school_id") 54 }, 55 inverseJoinColumns={//与当前类关联的类的ID 56 @JoinColumn(name="teacher_id"), 57 } 58 59 ) 60 public Set<Teacher> getMyTeachers() { 61 return myTeachers; 62 } 63 public void setMyTeachers(Set<Teacher> myTeachers) { 64 this.myTeachers = myTeachers; 65 } 66 public String getStuName() { 67 return stuName; 68 } 69 public void setStuName(String stuName) { 70 this.stuName = stuName; 71 } 72 @Id 73 public String getSchoolName() { 74 return schoolName; 75 } 76 public void setSchoolName(String schoolName) { 77 this.schoolName = schoolName; 78 } 79 @Id 80 public int getId() { 81 return id; 82 } 83 public void setId(int id) { 84 this.id = id; 85 } 86 87 }
1 import java.sql.Connection; 2 import java.util.HashSet; 3 import java.util.Set; 4 5 import org.hibernate.Session; 6 import org.hibernate.SessionFactory; 7 import org.hibernate.cfg.Configuration; 8 9 import com.pt.hibernate.Student; 10 import com.pt.hibernate.Teacher; 11 import com.pt.hibernate.Teacher_stu; 12 import com.pt.treeStrut.ArticleTree; 13 14 15 public class Test { 16 public static void main(String[] arges){ 17 Configuration cfg = new Configuration(); 18 SessionFactory factory = cfg.configure().buildSessionFactory(); 19 Student stu = new Student(20111913,"潘腾5","独羊岗中学"); 20 Teacher tea = new Teacher(1011,"JinLei"); 21 tea.getMyStudents().add(stu); 22 stu.getMyTeachers().add(tea); 23 Teacher_stu s_t= new Teacher_stu(1012,stu,tea); 24 stu.getT_s().add(s_t); 25 26 Session ss = factory.getCurrentSession(); 27 ss.beginTransaction(); 28 ss.save(stu); 29 ss.getTransaction().commit(); 30 factory.close(); 31 } 32 33 public static void printTree(ArticleTree parent,int level){ 34 for(int i = 0; i< level; i++){ 35 System.out.print("--"); 36 } 37 System.out.println(parent); 38 for(ArticleTree article : parent.getSons()){ 39 printTree(article, level + 1); 40 } 41 } 42 }