其中一个多方持有另一个多方的集合对象
比如教师和学生构成多对多的关系,学生就持有教师的的关系
学生和教师两个表外键关系的维护交给一个中间表,所以要创建中间表,不过这个中间表可以通过注解自动生成。
学生类要添加两个注解:
@ManyToMany
@JoinTable(
name=”teachers_students”,
joinColumns={@JoinColumn(name=”sid”)},
inverseJoinColumns={@JoinColumn(name=”tid”)}
)
@JoinTable负责维护和生成中间表,name指定了它的表名,后边两个指定的控制的相应字段。这里sid是学生表的外键,tid是教师表的外键。
除了学生类,还要创建教师类。Teachers将来会被映射成一张表,所以要指定主键
@Entity
public class Teachers {
@Id
@GeneratedValue(generator="tid")
@GenericGenerator(name="tid",strategy="assigned")
@Column(length=4)
private String tid;
private String tname;
public Teachers(){
}
public Teachers(String tid, String tname) {
super();
this.tid = tid;
this.tname = tname;
}
public String getTid() {
return tid;
}
public void setTid(String tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
}
因为是单向的,可以让学生持有教师的集合
@Entity
public class Students {
private int sid;
private String sname;
private String gender;
private Date birthday;
private String major;
private Set<Teachers> teachers;
public Students(){
}
public Students(String sname, String gender, Date birthday,
String major) {
//super();
//这里不传入sid,因为是自动增长的,不需要赋值
this.sname = sname;
this.gender = gender;
this.birthday = birthday;
this.major = major;
}
@Id
@GeneratedValue
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
@ManyToMany
@JoinTable(
name="teachers_students",
joinColumns={@JoinColumn(name="sid")},
inverseJoinColumns={@JoinColumn(name="tid")}
)
public Set<Teachers> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teachers> teachers) {
this.teachers = teachers;
}
}
修改配置文档
<mapping class="mtm_fk.Students"/>
<mapping class="mtm_fk.Teachers"/>
测试类中只保留以下方法:
@Test
public void testSchemaExport() {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
// 创建会话工厂对象
SessionFactory sessionFactory = config
.buildSessionFactory(serviceRegistry);
SchemaExport export = new SchemaExport(config);
export.create(true, true);
}
结果成功生成了students表、teachers表和中间表teachers_students
然后测试添加记录:
@Test
public void addStudents() {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
// 创建会话工厂对象
SessionFactory sessionFactory = config
.buildSessionFactory(serviceRegistry);
//创建会话对象
Session session = sessionFactory.getCurrentSession();
//创建事务对象
Transaction tx = session.beginTransaction();
//先创建教师对象
Teachers t1 = new Teachers("T001","张老师");
Teachers t2 = new Teachers("T002","李老师");
Teachers t3 = new Teachers("T003","陈老师");
Teachers t4 = new Teachers("T004","刘老师");
//然后创建四个学生对象
Students s1 = new Students("张三", "男", new Date(), "计算机");
Students s2 = new Students("李四", "女", new Date(), "计算机");
Students s3 = new Students("王五", "女", new Date(), "计算机");
Students s4 = new Students("赵六", "男", new Date(), "计算机");
//创建四个教师的集合
Set<Teachers> set1 = new HashSet<Teachers>();
set1.add(t1);
set1.add(t2);
Set<Teachers> set2 = new HashSet<Teachers>();
set2.add(t3);
set2.add(t4);
Set<Teachers> set3 = new HashSet<Teachers>();
set3.add(t1);
set3.add(t3);
set3.add(t4);
Set<Teachers> set4 = new HashSet<Teachers>();
set4.add(t2);
set4.add(t3);
set4.add(t4);
//分别设置四个学生的教师集合
s1.setTeachers(set1);
s2.setTeachers(set2);
s3.setTeachers(set3);
s4.setTeachers(set4);
//先保存教师
session.save(t1);
session.save(t2);
session.save(t3);
session.save(t4);
//再保存学生
session.save(s1);
session.save(s2);
session.save(s3);
session.save(s4);
tx.commit();
}
可以成功添加数据,顺便看一下中间表的内容
多对多单向外键关联
双方都持有对方的集合,其中一方设置,比如说是教师类:
@ManyToMany(mappedBy=”teachers”)
另一方,学生类中设置:
@ManyToMany
@JoinTable(
name=”teachers_students”,
joinColumns={@JoinColumn(name=”sid”)},
inverseJoinColumns={@JoinColumn(name=”tid”)}
)
刚刚的例子中,教师类添加
@ManyToMany(mappedBy="teachers")
private Set<Students> stus;
学生类不需要修改。
配置文件要配置好两个类。
刚刚的测试类也不需要修改。