? ? Hibernate對于數據庫的操作,全部利用面向對象的思維來理解和實現的。一般的單獨表的映射,相信大家都沒有問題,但是對于一些表之間的特殊關系,Hibernate提供了一些獨特的方式去簡化它。
? ? 今天就來說說多對一的關聯映射。
? ? 數據庫中有多對一的關系,Hibernate自然也有對象的多對一的關聯關系。比如用戶和用戶組,一個用戶只屬于一個組,一個組有多名用戶。我們就可以說用戶和用戶組的關系就是多對一的關系。用對象的uml圖表示一下:

? ? 在Hibernate中如何來實現呢?首先定義這兩個實體類:
~~~
package com.bjpowernode.hibernate;
/**
* 用戶組
* @author Longxuan
*
*/
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;
}
}
package com.bjpowernode.hibernate;
/**
* 用戶類
* @author Longxuan
*
*/
public class User {
private int id;
private String name;
private Group group;
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.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;
}
}
~~~
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 name="foo">
<property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property><!-- 設置是否顯示生成sql語句 -->
<property name="hibernate.format_sql">false</property><!-- 設置是否格式化sql語句-->
<mapping resource="com/bjpowernode/hibernate/Tables.hbm.xml" />
</session-factory>
</hibernate-configuration>
~~~
hibernate.properties配置文件:
~~~
## MySQL
hibernate.dialect org.hibernate.dialect.MySQLDialect
#hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost:3306/hibernate_many2one
hibernate.connection.username root
hibernate.connection.password root
~~~
? ? 這是最基礎的準備工作,多對一映射在對數據進行更改時,會有一些限制。當沒有該用戶組時,添加用戶,就會出錯,當該用戶組有用戶時,刪除該用戶組也會報錯。
? ? 我們當然可以按一般的方法來做。添加的時候,先手動添加組,再添加用戶。刪除時,先刪除所有的用戶,再刪除用戶組。但是Hibernate為我們提供了一種便捷的方式——many-to-one。在映射文件hbm.xml中配置后,就可以不用再想那些限制了。Hibernate會自動添加上所引用的數據。
? ? 給出映射文件:
~~~
<?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.bjpowernode.hibernate.User" table="t_user">
<id name="id">
<generator class="native" />
</id>
<property name="name"></property>
<many-to-one name="group" column="groupid" cascade="save-update"></many-to-one>
</class>
<class name="com.bjpowernode.hibernate.Group" table="t_group">
<id name="id">
<generator class="native" />
</id>
<property name="name"></property>
</class>
</hibernate-mapping>
~~~
? ? ?配置了many-to-one會自動在t_user表中創建外鍵groupid,與t_group的id映射。

? many-to-one標簽用到了cascade,指定兩個對象之間的操作聯動關系,對一個對象執行了操作之后,對其指定的級聯對象也需要執行相同的操作。其屬性值如下:?
- all:在所有的情況下都執行級聯操作;
- none:在所有情況下都不執行級聯操作;
- save-update:在保存和更新的時候執行級聯操作;、
- delete:在刪除的時候執行級聯操作。
? 測試類Many2OneTest:
~~~
package com.bjpowernode.hibernate;
import junit.framework.TestCase;
import org.hibernate.Session;
public class Many2OneTest extends TestCase {
/**
* 測試添加用戶
*/
public void testSave3(){
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
Group group = new Group();
group.setName("提高班");
User user1 = new User();
user1.setName("張三");
user1.setGroup(group);
User user2 = new User();
user2.setName("李四");
user2.setGroup(group);
//普通方法 :必須先保存group,再保存user
//配置了many-to-one 則不用再手動save group了。
//session.save(group);
session.save(user1);
session.save(user2);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
}
~~~
? ? 結果圖:

執行測試前:
, 執行測試后:?
? ? 用many-to-one進行配置后,hibernate會自動去添加外鍵,而我們做的任何操作都不需要去考慮它的結構,也不用手動去維護這個關系,關系由Hibernate自動維護。這就是Hibernate的魅力所在。
- 前言
- Struts 簡單小結
- 深入淺出了解Struts的處理流程(有圖有真相)
- struts標簽+jstl標簽之國際化實例
- 一口一口吃掉Hibernate(二)——別被世俗蒙蔽了雙眼:Hibernate中Session之get和load方法的真正區別
- 一口一口吃掉Hibernate(一)——使用SchemaExport生成數據表
- 一口一口吃掉Hibernate(三)——Hibernate給表和字段設置前后綴及分隔符
- 一口一口吃掉Hibernate(四)——多對一單向關聯映射
- 一口一口吃掉Hibernate(五)——一對多單向關聯映射
- 一口一口吃掉Hibernate(六)——多對多關聯映射
- 一口一口吃掉Hibernate(七)——繼承映射
- 一口一口吃掉Hibernate(八)——Hibernate中inverse的用法
- 一覽Spring全貌
- 包辦婚姻的Spring IoC
- 3幅圖讓你了解Spring AOP
- Spring Aop實例之xml配置
- Spring Aop實例之AspectJ注解配置