hibernate ——关联关系

时间:2023-01-26 21:53:38

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&amp;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>

hibernate.cfg.xml

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;
} }

Husband.java

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;
}

Wife

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();
}
}

Test

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;
} }

Wife

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;
}
}

Son

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;
} }

Husband

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;
} }

Husband.java

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;
} }

Wife.java

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;
} }

Wife.java

7、多对多单向关联

  在数据库中,针对多对多的关系,如:学生与老师的关系,一般都是有一张中间表维护!同时,需要建立一张中间表对应的类~~

 package com.pt.hibernate;

 import java.util.Set;

 import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany; import org.hibernate.engine.internal.Cascade; @Entity
@IdClass(value=UnionId.class)
public class Student {
String schoolName;
int id;
String stuName;
Set<Teacher> myTeachers;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(
name="teacher_stu",
joinColumns={//当前类的ID
@JoinColumn(name="stu_id"),
@JoinColumn(name="school_id")
},
inverseJoinColumns={//与当前类关联的类的ID
@JoinColumn(name="teacher_id"),
} )
public Set<Teacher> getMyTeachers() {
return myTeachers;
}
public void setMyTeachers(Set<Teacher> myTeachers) {
this.myTeachers = myTeachers;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
@Id
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
} }

Student.java

 package com.pt.hibernate;

 import java.util.Set;

 import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany; import org.hibernate.engine.internal.Cascade; @Entity
public class Teacher {
int id;
String name;
String courese; //教授课程
Set<Student> myStudents;
@ManyToMany(mappedBy="myTeachers",cascade=CascadeType.ALL)
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;
} }

Teacher.java

  生成的表结构如下:

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;
} }

Teacher.java

  

总结:1、双向关联,必用mappedBy属性

   2、单向与双向关联,对于数据库结构是没有区别的,区别在于程序中是否可以通过一方寻找另一方;

      如:A与B单向关联,只可以通过A找B,通过B找不到A,

        双向关联,则可以通过A找B,也可以通过B找A;

多对多补充:

 package com.pt.hibernate;

 import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.Table; @Entity
@Table(name="teacher_stu")
public class Teacher_stu {
int id;
Student student; Teacher teacher;
public Teacher_stu() {
} public Teacher_stu(int in_id,Student in_student,Teacher in_teacher) {
this.id = in_id;
this.student = in_student;
this.teacher = in_teacher;
} @ManyToOne
//最好指定列名 别用默认的
@JoinColumns({
@JoinColumn(name="stu_id"),
@JoinColumn(name="school_id")
}
)
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@ManyToOne
@JoinColumn(name="teacher_id")
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
} }

Teacher_stu

 package com.pt.hibernate;

 import java.io.Serializable;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany; import org.hibernate.engine.internal.Cascade; @Entity
public class Teacher {
int id;
String name;
String courese; //教授课程
Set<Student> myStudents;
Set<Teacher_stu> t_s; public Teacher() {
} public Teacher(int in_id,String in_name) {
this.id = in_id;
this.name = in_name;
} @OneToMany(mappedBy="teacher")
public Set<Teacher_stu> getT_s() {
return t_s;
}
public void setT_s(Set<Teacher_stu> t_s) {
this.t_s = t_s;
} @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;
} }

Teacher.java

 package com.pt.hibernate;

 import java.io.Serializable;
import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany; import org.hibernate.engine.internal.Cascade; @Entity
@IdClass(value=UnionId.class)
public class Student implements Serializable{
String schoolName;
int id;
String stuName;
Set<Teacher> myTeachers;
Set<Teacher_stu> t_s; public Student() {
myTeachers = new HashSet<Teacher>();
t_s = new HashSet<Teacher_stu>();
} public Student(int in_id,String in_stuName,String in_schoolName) {
this.id = in_id;
this.stuName = in_stuName;
this.schoolName = in_schoolName;
myTeachers = new HashSet<Teacher>();
t_s = new HashSet<Teacher_stu>();
} @OneToMany(mappedBy="student")
public Set<Teacher_stu> getT_s() {
return t_s;
}
public void setT_s(Set<Teacher_stu> t_s) {
this.t_s = t_s;
} @ManyToMany(cascade=CascadeType.ALL)
@JoinTable(
name="teacher_stu",
joinColumns={//当前类的ID
@JoinColumn(name="stu_id"),
@JoinColumn(name="school_id")
},
inverseJoinColumns={//与当前类关联的类的ID
@JoinColumn(name="teacher_id"),
} )
public Set<Teacher> getMyTeachers() {
return myTeachers;
}
public void setMyTeachers(Set<Teacher> myTeachers) {
this.myTeachers = myTeachers;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
@Id
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
} }

Student.java

 import java.sql.Connection;
import java.util.HashSet;
import java.util.Set; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; import com.pt.hibernate.Student;
import com.pt.hibernate.Teacher;
import com.pt.hibernate.Teacher_stu;
import com.pt.treeStrut.ArticleTree; public class Test {
public static void main(String[] arges){
Configuration cfg = new Configuration();
SessionFactory factory = cfg.configure().buildSessionFactory();
Student stu = new Student(20111913,"潘腾5","独羊岗中学");
Teacher tea = new Teacher(1011,"JinLei");
tea.getMyStudents().add(stu);
stu.getMyTeachers().add(tea);
Teacher_stu s_t= new Teacher_stu(1012,stu,tea);
stu.getT_s().add(s_t); Session ss = factory.getCurrentSession();
ss.beginTransaction();
ss.save(stu);
ss.getTransaction().commit();
factory.close();
} public static void printTree(ArticleTree parent,int level){
for(int i = 0; i< level; i++){
System.out.print("--");
}
System.out.println(parent);
for(ArticleTree article : parent.getSons()){
printTree(article, level + 1);
}
}
}

Test.java