hibernate里的一对多one-to-many(以学生和班级为例子)
[color=red]1.双向关联情况下[/color]
Classes.java:
Student.java
Classes.hbm.xml
Student.hbm.xml
测试类
根据学生查找班级:
[color=red]2.单向关联情况下[/color]
把一方的Set集合去掉,对应的.hbm.xml里的部分也给去掉。
即去掉:
测试类:
[color=red]1.双向关联情况下[/color]
Classes.java:
package com.domain;
import java.util.HashSet;
import java.util.Set;
public class Classes implements java.io.Serializable {
private Integer id;
private String name;
private Set students = new HashSet(0);
public Classes() {
}
public Classes(String name) {
this.name = name;
}
public Classes(String name, Set students) {
this.name = name;
this.students = students;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set getStudents() {
return this.students;
}
public void setStudents(Set students) {
this.students = students;
}
}
Student.java
package com.domain;
public class Student implements java.io.Serializable {
private Integer id;
private Classes classes;
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public Student(Classes classes, String name) {
this.classes = classes;
this.name = name;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Classes getClasses() {
return this.classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Classes.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="com.domain.Classes" table="classes" catalog="hibernatetest">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" not-null="true" />
</property>
<!-- inverse="true" 主动权反转给了Classes,cascade="all"级联students表里的数据会级联被删除或更新等,这里设置的是all,lazy="true" students表里的数据会lazy加载 -->
<set name="students" inverse="true" cascade="all" lazy="true">
<key>
<column name="classId" />
</key>
<one-to-many class="com.domain.Student" />
</set>
</class>
</hibernate-mapping>
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="com.domain.Student" table="student" catalog="hibernatetest">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<!-- cascade="all" classes表里的数据会被级联操作 fetch="select" classes表里的数据会以左外连接的形式取出来(根据学生查找班级的具体信息时),如果值是join 则进行内连接-->
<many-to-one name="classes" class="com.domain.Classes" fetch="select" cascade="all">
<column name="classId" />
</many-to-one>
<property name="name" type="java.lang.String">
<column name="name" not-null="true" />
</property>
</class>
</hibernate-mapping>
测试类
package com.dao;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.domain.Classes;
import com.domain.Student;
public class Test {
public static void main(String[] args){
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
//添加数据
/*
//定义学生一
Student student1 = new Student();
student1.setName("zhansan");
//定义学生二
Student student2 = new Student();
student2.setName("lisi");
//定义班级0201班
Classes classes = new Classes();
classes.setName("0201");
//双向关联给主表设置关联
classes.getStudents().add(student1);
classes.getStudents().add(student2);
//双向关联给从表设置关联
student1.setClasses(classes);
student2.setClasses(classes);
session.save(classes);
tx.commit();
session.close();
*/
//修改多方
//修改学生,必须给要修改的这个学生每个属性都赋值
/*Student student = new Student();
student.setName("wangwu111");
student.setId(1);
Classes classes = new Classes();
classes.setId(1);
classes.setName("0201");
//如果下面这句代码不要的话,则修改执行的sql为update hibernatetest.student set classId=?, name=? where id=?,修改后classId为null(即使classId原来有值,也会被改为null),所以,必须给要修改的这个学生每个属性都赋值
student.setClasses(classes);
//修改
session.update(student);
tx.commit();
session.close();*/
//修改执行的sql:
/*
Hibernate: update hibernatetest.student set classId=?, name=? where id=?
Hibernate: update hibernatetest.classes set name=? where id=?
级联修改
*/
//修改一方,不需要给Set集合属性赋值
/*
Classes classes = new Classes();
classes.setId(1);
classes.setName("0210");
//修改
session.update(classes);
tx.commit();
session.close();*/
//执行的sql:Hibernate: update hibernatetest.classes set name=? where id=?
//查询操作
String hql = "from Classes c where c.id=1";
Query query = session.createQuery(hql);
Classes classes = (Classes)query.uniqueResult();
System.out.println(classes.getId() + " : " + classes.getName() + " : ");
//如果再这里进行session.close();那么需要写下面的判断,强制性去拿student表里的数据
// if(!Hibernate.isInitialized(classes.getStudents())){
// Hibernate.initialize(classes.getStudents());
// }
//因为Student设置的lazy,执行下面的语句时,才去student表查询
Set set = classes.getStudents();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
Student cla = (Student)iterator.next();
System.out.println(cla.getId() + " : " + cla.getName());
}
session.close();
//执行的sql
/*
Hibernate: select classes0_.id as id1_, classes0_.name as name1_ from hibernatetest.classes classes0_ where classes0_.id=1
1 : 0210 :
Hibernate: select students0_.classId as classId1_, students0_.id as id1_, students0_.id as id0_0_, students0_.classId as classId0_0_, students0_.name as name0_0_ from hibernatetest.student students0_ where students0_.classId=?
2 : zhansan
1 : wangwu111
*/
}
}
根据学生查找班级:
package com.dao;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import com.domain.Student;
public class TestSelect {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
String hql = "from Student s where s.classes.id=1";
Query query = session.createQuery(hql);
List<Student> list = query.list();
for(int i=0;i<list.size();i++){
Student student = (Student)list.get(i);
System.out.println(student.getId() + " : " + student.getName() + " : " + student.getClasses().getId() + " : " + student.getClasses().getName());
//执行的sql:Hibernate: select student0_.id as id0_, student0_.classId as classId0_, student0_.name as name0_ from hibernatetest.student student0_ where student0_.classId=1
//System.out.println(student.getId() + " : " + student.getName());
}
session.close();
/**
执行的sql为:
Hibernate: select student0_.id as id0_, student0_.classId as classId0_, student0_.name as name0_ from hibernatetest.student student0_ where student0_.classId=1
Hibernate: select classes0_.id as id1_0_, classes0_.name as name1_0_ from hibernatetest.classes classes0_ where classes0_.id=?
*/
}
}
[color=red]2.单向关联情况下[/color]
把一方的Set集合去掉,对应的.hbm.xml里的部分也给去掉。
即去掉:
<set name="students" inverse="true" cascade="all" lazy="true">
<key>
<column name="classId" />
</key>
<one-to-many class="com.domain.Student" />
</set>
测试类:
package com.dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.domain.Classes;
import com.domain.Student;
public class TestInsert {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
//定义班级0201班
Classes classes = new Classes();
classes.setName("0201test");
//定义学生一
Student student1 = new Student();
student1.setName("zhansantest");
student1.setClasses(classes);
//定义学生二
Student student2 = new Student();
student2.setName("lisitest");
student2.setClasses(classes);
//classes一定要最先被save
session.save(classes);
session.save(student1);
session.save(student2);
tx.commit();
session.close();
/**
执行的sql:
Hibernate: insert into hibernatetest.classes (name) values (?)
Hibernate: insert into hibernatetest.student (classId, name) values (?, ?)
Hibernate: insert into hibernatetest.student (classId, name) values (?, ?)
*/
}
}