双向多对多
学生和老师之间的关系是多对多的,一个老师可以对应多个学生,而一个学生也可以对应多个老师,所有老师与学生之间的关系需要生成三张表,学生表、教师表和中间表。中间表中分为两列,一列为student_id,另一列为teacher_id,这两列合起来为中间表的主键
在Student.java中,设定了三个属性,id,name和Teacher的集合对象
Teacher的集合对象用来存放一个学生所对应的所有老师
private int id;
private String name;
private Set<Teacher> teachers;
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
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;
}
Student.hbm.xml
<hibernate-mapping
package="com.hbsi.domain">
<class name="Student" table="student">
<id name="id" column="id">
<!-- native自动增长 根据不同的底层数据库选择产生不同的策略 -->
<generator class="native"/>
</id>
<property name="name"/>
<set name="teachers" table="teacher_student">
<key column="student_id"></key>
<many-to-many class="Teacher" column="teacher_id"/>
</set>
</class>
</hibernate-mapping>
除了name这个属性以外,还有teachers,teachers是一个集合对象,它去与中间表teacher_student相关联,在学生表中通过student_id去查找中间表,在中间表中通过teacher_id去查教师表。
在Teacher.java中,设定了三个属性,id,name和Student的集合对象
Student的集合对象用来存放一个老师所对应的所有学生
private int id;
private String name;
private Set<Student> students;//反应的是教过得学生
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 Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
Teacher.hbm.xml
<hibernate-mapping
package="com.hbsi.domain">
<class name="Teacher" table="teacher">
<id name="id" column="id">
<!-- native自动增长 根据不同的底层数据库选择产生不同的策略 -->
<generator class="native"/>
</id>
<property name="name"/>
<!-- table属性是用来指定中间表的名字 -->
<set name="students" table="teacher_student">
<!-- 以teacher_id为参照查中间表 -->
<key column="teacher_id"></key>
<!-- 以student_id为参照通过中间表去查学生表 -->
<many-to-many class="Student" column="student_id"/>
</set>
</class>
</hibernate-mapping>
注意:记得一定要去配置文件hibernate.cfg.xml中去配置
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- hbm2ddl的四种状态:create、update、create_drop、validate -->
<!-- create:在程序运行时生成表格,在程序结束时不会销毁表格,在下次运行时销毁重建 -->
<!-- update:在原有继续保持的基础上,更新 -->
<!-- create_drop:在程序运行时生成表格,程序运行结束时销毁表格 -->
<!-- validate:验证创建数据库表结构 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 显示产生的sql语句 -->
<property name="hibernate.show_sql">true</property>
<mapping resource="com/hbsi/domain/Student.hbm.xml"/>
<mapping resource="com/hbsi/domain/Teacher.hbm.xml"/>
</session-factory>
</hibernate-configuration>
测试文件ManyToMany.java
public static void add(){
//多对多得添加
Session s=null;
Transaction tx=null;
try{
s=HibernateUtil.getSession();
tx=s.beginTransaction();
//添加
Teacher t1=new Teacher();
t1.setName("老师1");
Teacher t2=new Teacher();
t2.setName("老师2");
Student s1=new Student();
s1.setName("学生一");
Student s2=new Student();
s2.setName("学生二");
Set<Student> ss=new HashSet<Student>();
ss.add(s1);
ss.add(s2);
//如果把下面两句话注释了,运行不报错,并且能正确报存,但表中的数据就不能体现出关联了,也就是中间表位空
t1.setStudents(ss);
t2.setStudents(ss);
/* 因为上面告诉老师自己的学生有哪些了,这是一个映射关系,会在中间表中查四条记录,
所有下面如果再告诉学生自己的老师有哪些,这也是一个映射关系,
又会在中间表中查四条记录,与原来的记录相同,因为中间表的主键
为两者的组合,所以这样就会出现主键相同的情况产生冲突就会报错*/
/*Set<Teacher> ts=new HashSet<Teacher>();
ts.add(t1);
ts.add(t2);
//告诉学生自己的老师有哪些
s1.setTeachers(ts);
s2.setTeachers(ts);*/
s.save(t1);
s.save(t2);
s.save(s1);
s.save(s2);
tx.commit();
}finally{
if(s!=null){
s.close();
}
}
}
//查询
public static void query(int id){
Session s=null;
try{
//查询
s=HibernateUtil.getSession();
//根据老师查学生
Teacher t=(Teacher) s.get(Teacher.class, id);
System.out.println("教师的姓名:"+t.getName());
System.out.println("教师的学生列表");
//利用迭代器迭代出学生列表
Iterator<Student> it=t.getStudents().iterator();
while(it.hasNext()){
Student student=it.next();
System.out.println(student.getName()+" ");
}
System.out.println();
//根据学生查老师
Student student1=(Student) s.get(Student.class,id);
System.out.println("学生的姓名:"+student1.getName());
System.out.println("学生的教师列表");
//利用迭代器迭代出学生列表
Iterator<Teacher> it1=student1.getTeachers().iterator();
while(it1.hasNext()){
Teacher teacher=it1.next();
System.out.println(teacher.getName()+" ");
}
System.out.println();
}finally{
if(s!=null){
s.close();
}
}
}