1. 程式人生 > >hibernate學習4之one-to-many單向關聯(不推薦)

hibernate學習4之one-to-many單向關聯(不推薦)

一對多和多對一的對映策略是一樣的,只是站的角度不同.

多對一關聯對映:在多的一端加入一個外來鍵指向一的一端,它維護的關係是多指向一
一對多關聯對映:在多的一端加入一個外來鍵指向一的一端,它維護的關係是一指向多

先上配置檔案:

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_one2many_1</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">bjsxt</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.show_sql">true</property>
		
		<mapping resource="com/bjsxt/hibernate/Classes.hbm.xml"/>
		<mapping resource="com/bjsxt/hibernate/Student.hbm.xml"/>
	</session-factory>
</hibernate-configuration>


public class Student {
	private int id;
	private String name;
	//setter,getter
}


import java.util.Set;

public class Classes {
	private int id;
	private String name;
	private Set students; //一對多,一個班級對應很多學生
	//setter,getter
	
}

Student.hbm.xml:
<?xml version="1.0"?>
<!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.bjsxt.hibernate.Student" table="t_student">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
	</class>
</hibernate-mapping>

Classes.hbm.xml:
<?xml version="1.0"?>
<!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.bjsxt.hibernate.Classes" table="t_classes">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="students">
			<key column="classesid"/>
			<one-to-many class="com.bjsxt.hibernate.Student"/>
		</set>
	</class>
</hibernate-mapping>

上面這個配置在Student一端加入了一個classesid外來鍵;也說明set裡存放的是Student物件

測試一下:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import junit.framework.TestCase;

import org.hibernate.Session;

public class One2ManyTest extends TestCase {

	public void testSave1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Student student1 = new Student();
			student1.setName("10");
			session.save(student1);//先save
			
			Student student2 = new Student();
			student2.setName("祖兒");
			session.save(student2);//先save
			
			Set students = new HashSet();
			students.add(student1);
			students.add(student2);
			
			Classes classes = new Classes();
			classes.setName("尚學堂");
			classes.setStudents(students);
			
			//可以正確儲存
			session.save(classes);
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	
	
	public void testLoad1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Classes classes = (Classes)session.load(Classes.class, 1);
			System.out.println("classes.name=" + classes.getName());
			Set students = classes.getStudents();
			for (Iterator iter=students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println("student.name=" + student.getName());
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}		
}


在一一端維護關係的缺點:
* 如果將t_student表裡的classesid欄位設定為非空,則無法儲存
* 因為不是在student這一端維護關係,所以student不知道是哪個班的,
  所以需要發出多餘的update語句來更新關係

因為一對多(單向關聯)會發出額外的sql語句,效率沒有多對一高,所以通常情況下不採用一對多的單向關聯,採用雙向關聯比較妥當!