Hibernate多对多数据关联
多对多的关联
例如:学生选课,一个学生可以选多门课程,一门课程可以有多个学生
create table student
(
sid int primary key,
sname varchar(20) not null,
age int not null,
)
create table course
(
cid int identity(1,1) primary key,
cname varchar(20) not null,
score int not null,
)
create table studentcourse
(
sid int,
cid int,
constraint FK_CID foreign key(cid) references course(cid),
constraint FK_SID foreign key(sid) references student(sid)
)
建立POJO 类之间的关系
Student.java:
import java.util.*;
public class Student {
private int sid;
private String sname;
private int age;
private Set course=new HashSet(0);
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Set getCourse() {
return course;
}
public void setCourse(Set course) {
this.course = course;
}
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;
}
}
Course.java:
import java.util.*;
public class Course {
private int cid;
private String cname;
private int score;
private Set student=new HashSet(0);
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Set getStudent() {
return student;
}
public void setStudent(Set student) {
this.student = student;
}
}
配置映射文件:
Student.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="student.Student" table="student" catalog="myshop" schema="dbo">
<id name="sid" type="java.lang.Integer">
<column name="sid"></column>
<generator type="java.lang.String">
<column name="sname" length="20" not-null="true"></column>
</property>
<property name="age" type="java.lang.Integer">
<column name="age" length="20" not-null="true"/>
</property>
<!--name表示Student类中Set的名称,多对多使用studentcourse表维护关系 -->
<set name="course" table="studentcourse" cascade="all">
<key>
<!-- 学生表在关系表中的外键 -->
<column name="sid"></column>
</key>
<!--Set集合中每个元素的类型, -->
<many-to-many encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="student.Course" table="course" catalog="myshop" schema="dbo">
<id name="cid" type="java.lang.Integer">
<column name="cid"></column>
<generator type="java.lang.String">
<column name="cname" length="20" not-null="true"></column>
</property>
<property name="score" type="java.lang.Integer">
<column name="score" not-null="true"/>
</property>
<!-- name 表示Course中Set集合名称,及使用的关系表 -->
<!-- inverse 表示是否有主动权,为true表示没有主动权
如果这里不把inverse设置成false,那么还会插入一条
-->
<set name="student" table="studentcourse" inverse="true">
<key>
<!-- 课程表在关系表中的外键 -->
<column name="cid"></column>
</key>
<!--Set集合中每个元素的类型 -->
<many-to-many class="student.Student">
<!--Student表在关系表中的外键 -->
<column name="sid"></column>
</many-to-many>
</set>
</class>
</hibernate-mapping>
测试类:
import java.util.*;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class Test {
private SessionFactory sessionFactory;
private Session session;
public Test()
{
sessionFactory=new Configuration().configure().buildSessionFactory();
session=sessionFactory.openSession();
}
public void doCreate()
{
Student s1=new Student();
Student s2=new Student();
s1.setSid(3);
s1.setSname("张三");
s1.setAge(20);
s2.setSid(2);
s2.setSname("李四");
s2.setAge(22);
Course c1=new Course();
c1.setCname("JAVA");
c1.setScore(98);
s1.getCourse().add(c1);
s2.getCourse().add(c1);
c1.getStudent().add(s1);
c1.getStudent().add(s2);
session.save(s1);
session.beginTransaction().commit();
session.close();
}
public static void main(String[]args)
{
new Test().doCreate();
}
}
运行结果:
Hibernate: insert into myshop.dbo.student (sname, age, sid) values (?, ?, ?)
Hibernate: insert into myshop.dbo.course (cname, score) values (?, ?)
Hibernate: insert into studentcourse (sid, cid) values (?, ?)
此时,插入的只是第一个学生,如果在插入第二个学生,你会发现课程名称也被插入。这是因为对于Hibernate来说课程是一个新的实体,如果
是新的实体,则肯定会重新插入
public void doCreate()
{
Student s1=new Student();
s1.setSid(4);
s1.setSname("王五");
s1.setAge(20);
Course c1=(Course)session.get(Course.class, 1);
c1.setCname("JAVA");
c1.setScore(98);
s1.getCourse().add(c1);
c1.getStudent().add(s1);
session.save(s1);
session.beginTransaction().commit();
session.close();
}