1. 程式人生 > >Many-to-One對映

Many-to-One對映

舉例如下:

1.Group.java

package edu.study.hibernate;

public class Group {

	private int id;
	
	private String name;

	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;
	}
	
}

2.User.java

package edu.study.hibernate;

public class User {

	private int id;
	
	private String name;
	
	private Group group;

	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 Group getGroup() {
		return group;
	}

	public void setGroup(Group group) {
		this.group = group;
	}
	
}

3.Group.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="edu.study.hibernate.Group" table="t_group">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
	</class>	
</hibernate-mapping>

4.User.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="edu.study.hibernate.User" table="t_user">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		<many-to-one name="group" column="groupid" cascade="all"></many-to-one>
	</class>	
</hibernate-mapping>

5.hibernate.cfg.xml配置檔案

<!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://127.0.0.1/hibernate_many2one</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.show_sql">true</property>
		
	<mapping resource="edu/study/hibernate/User.hbm.xml"/>
	<mapping resource="edu/study/hibernate/Group.hbm.xml"/>
	</session-factory>
</hibernate-configuration>


6.測試程式碼

 Group group=new Group();
			  group.setName("研發部");
			  
			  User u1=new User();
			  u1.setName("小黃");
			  u1.setGroup(group);
			  
			  User u2=new User();
			  u2.setName("小張");
			  u2.setGroup(group);
			  
			  session.save(u1);
			  session.save(u2);

如果沒使用cascade屬性,會丟擲TransientObjectException異常,因為Group為transient狀態,User為persistent狀態,而persistent狀態物件不能引用transient狀態物件,因此會丟擲異常。正確的如下:

  Group group=new Group();
			  group.setName("研發部");
			  
			  //首先要儲存Group
			  session.save(group);
			  
			  User u1=new User();
			  u1.setName("小黃");
			  u1.setGroup(group);
			  
			  User u2=new User();
			  u2.setName("小張");
			  u2.setGroup(group);
			  
			  //可以正確儲存
			  session.save(u1);
			  session.save(u2);

注意:沒有使用cascade屬性的前提下,首先儲存Group,則Group物件成為了persistent狀態,從而當persistent狀態的User物件對其引用時,不會丟擲異常。

如果採用了級聯,即

		<many-to-one name="group" column="groupid" cascade="all"></many-to-one>

cascade屬性進行了設定,即使不首先儲存Group,也不會丟擲異常,並正確儲存。

  Group group=new Group();
			  group.setName("研發部");
			  
			  User u1=new User();
			  u1.setName("小黃");
			  u1.setGroup(group);
			  
			  User u2=new User();
			  u2.setName("小張");
			  u2.setGroup(group);
			  
			  session.save(u1);
			  session.save(u2);

因為採用了級聯cascade屬性,會首先儲存Group,所以不會丟擲異常。



總結:

(1)多對一對映:會在多的一端(User)加入外來鍵,指向一的一端(Group),外來鍵的定義由column屬性決定,如果沒有該屬性,預設的外來鍵與實體的屬性一致。如

<many-to-one name="group" column="groupid" cascade="all"></many-to-one>

(2)cascade:級聯的意思是指定兩個物件之間的操作聯動關係,對一個物件執行了操作之後,對其指定的級聯物件也需要執行相同的操作。

     其屬性值如下:

      all:在所有的情況下都執行級聯操作;

      none:在所有情況下都不執行級聯操作;

      save-update:在儲存和更新的時候執行級聯操作;

      delete:在刪除的時候執行級聯操作。