hibernate之one-to-many详细

阅读更多
1.
拿Classes和Student为例。
package com.test;

import java.util.Set;

public class Classes {
	
	private Integer classesId;
	private String classesName;
	private Set students;
	
	
	public Set getStudents() {
		return students;
	}
	public void setStudents(Set students) {
		this.students = students;
	}
	public Integer getClassesId() {
		return classesId;
	}
	public void setClassesId(Integer classesId) {
		this.classesId = classesId;
	}
	public String getClassesName() {
		return classesName;
	}
	public void setClassesName(String classesName) {
		this.classesName = classesName;
	}

}





	
		
			
		
		
		
		
			
			
				
		
	


package com.test;

public class Student {
	
	private Integer studentId;
	private String studentName;
	public Integer getStudentId() {
		return studentId;
	}
	public void setStudentId(Integer studentId) {
		this.studentId = studentId;
	}
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
}





	
		
			
		
		
	



测试类:
public  void testAdd(){
		
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		
		Student student1 = new Student();
		student1.setStudentName("zhangsan");
		
		Student student2 = new Student();
		student2.setStudentName("lisi");
		
		Classes classes = new Classes();
		classes.setClassesName("02-1");
		Set students = new HashSet();
		students.add(student1);
		students.add(student2);
		
		classes.setStudents(students);
		
		session.save(classes);
		
		
		session.getTransaction().commit();
		HibernateUtils.closeSession(session);
	}


这时会报org.hibernate.TransientObjectException异常,说明save classes对象时,student1和student2还是游离态对象,但是因为是一对多关系,所以一方Classes要知道多方的信息,这时多方还是游离态,所以就报错了。 可以设置让 Student对象级联更新。如下:

			
			
				
		


执行的sql代码如下:
Hibernate: insert into classes (classes_name) values (?)
Hibernate: insert into student (student_name) values (?)
Hibernate: insert into student (student_name) values (?)
Hibernate: update student set cls_id=? where student_id=?
Hibernate: update student set cls_id=? where student_id=?

可以看出是先insert,再update.这样有个缺点:如果数据量很大时会严重影响效率。可以通过inverse标签反转下。
	
			
			
				
		


执行的sql如下:
Hibernate: insert into classes (classes_name) values (?)
Hibernate: insert into student (student_name) values (?)
Hibernate: insert into student (student_name) values (?)

但是这时数据库记录里外键的值是null. 所以还需要配置双向关联。

Studnet.hbm.xml里添加:



Student.java里添加:
private Classes classes;
	public Classes getClasses() {
		return classes;
	}
	public void setClasses(Classes classes) {
		this.classes = classes;
	}


测试类里添加:
classes.setStudents(students);
		student1.setClasses(classes);
		student2.setClasses(classes);


如果不设置级联更新,也可以这样:
Classes.hbm.xml

			
			
				
		


Student.hbm.xml不变:



测试类:
public  void testAdd1(){
		
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		
		Student student1 = new Student();
		student1.setStudentName("zhangsan");
		
		Student student2 = new Student();
		student2.setStudentName("lisi");
		
		Classes classes = new Classes();
		classes.setClassesName("02-1");

		student1.setClasses(classes);
		student2.setClasses(classes);
		
		session.save(classes);
		session.save(student1);
		session.save(student2);
		
		session.getTransaction().commit();
		HibernateUtils.closeSession(session);
	}

执行sql:
Hibernate: insert into classes (classes_name) values (?)
Hibernate: insert into student (student_name, cls_id) values (?, ?)
Hibernate: insert into student (student_name, cls_id) values (?, ?)



总结:


1.都需要设置双向关联(指的是配置文件)
2.都需要设置inverse=true。(对级联来说,不用先insert,再update了)
3.设置了 cascade以后,save的是Classes对象,Student会级联保存。前提是双方关联:
         classes.setStudents(students);  
        student1.setClasses(classes);  
        student2.setClasses(classes);
4.没有设置cascade的话,save的是Student对象。不过save Student对象以前,要先save Classes对象。

你可能感兴趣的:(Hibernate,Java,SQL,XML,.net)