簡介
我們都已經(jīng)知道了Hibernate對于單表單記錄的基本操作了,但是我們知道,在這個(gè)世界上,事物與事物之間是有聯(lián)系的,而且關(guān)系是錯(cuò)綜復(fù)雜的,不僅有一對一,一對多,多對一還有多對多,對于數(shù)據(jù)庫中的數(shù)據(jù)也是如此,在通常的情況下,對數(shù)據(jù)庫中的帶有各種不同關(guān)系的數(shù)據(jù)進(jìn)行操作是常有的事情,于是我們開始嘗試使用Hibernate來進(jìn)行多個(gè)表之間有關(guān)系的數(shù)據(jù)之間的操作。
關(guān)系
我們知道關(guān)系有很多種,本文討論的是其中一對多和多對一的關(guān)系,其實(shí)這兩種關(guān)系是相同的,只不過是看對哪一方的對象來說,舉一個(gè)例子,公司里面有很多部門,也有很多員工,那么部門和員工是怎么組織起來的呢?一個(gè)部門領(lǐng)導(dǎo)著多個(gè)員工,多個(gè)員工同屬于一個(gè)部門

這就是一個(gè)經(jīng)典的一對多關(guān)系的例子
數(shù)據(jù)庫準(zhǔn)備
數(shù)據(jù)庫的建立不再贅述,簡單說一下表的準(zhǔn)備,這里我們需要用到兩張表,一張部門表,一張員工表


然后填入相關(guān)的預(yù)設(shè)數(shù)據(jù)


員工表外鍵設(shè)置

JavaBean類和映射準(zhǔn)備
這里我們就對應(yīng)數(shù)據(jù)庫建立兩個(gè)JavaBean類Dep和Emp
Dep.java:
package com.pojo;
import java.util.HashSet;
import java.util.Set;
public class Dep {
private int did;
private String dname;
private Set<Emp> emps = new HashSet<Emp>();
public int getDid() {
return did;
}
public void setDid(int did) {
this.did = did;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public Set<Emp> getEmps() {
return emps;
}
public void setEmps(Set<Emp> emps) {
this.emps = emps;
}
}
Emp.java:
package com.pojo;
public class Emp {
private int eid;
private String ename;
private Dep dep;
public int getEid() {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public Dep getDep() {
return dep;
}
public void setDep(Dep dep) {
this.dep = dep;
}
}
然后是各自對應(yīng)的Hibernate映射文件
Dep.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.pojo.Dep" table="dep">
<id name="did" column="did">
<generator class="assigned"></generator>
</id>
<property name="dname" column="dname"></property>
<set name="emps">
<key column="did"></key>
<one-to-many class="com.pojo.Emp" />
</set>
</class>
</hibernate-mapping>
Emp.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.pojo.Emp" table="emp">
<id name="eid" column="eid">
<generator class="assigned"></generator>
</id>
<property name="ename" column="ename"></property>
<many-to-one name="dep" column="did"></many-to-one>
</class>
</hibernate-mapping>
當(dāng)然最后不要忘了在全局配置文件中加上指定配置文件的命令
<mapping resource="com/pojo/Dep.hbm.xml"/>
<mapping resource="com/pojo/Emp.hbm.xml"/>
測試
至此準(zhǔn)備工作就完成了,接下來我們就可以在Test類中進(jìn)行測試
先簡單地嘗試一下看看外鍵的連接是否正確
Test.java
package com.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.pojo.Dep;
import com.pojo.Emp;
public class Test1 {
public static void main(String[] args) {
/* 使用hibernate之前的準(zhǔn)備 */
Configuration configuration = new Configuration().configure();
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
/* 這里我們獲得eid為1的emp對象,然后獲得對應(yīng)的dep對象并輸出相關(guān)屬性 */
Emp emp = (Emp) session.get(Emp.class, 1);
Dep dep = emp.getDep();
System.out.println(emp.getEid() + "\t" + emp.getEname() + "\t"
+ dep.getDname());
}
}
運(yùn)行之后可以看到控制臺輸出

說明我們的Hibernate沒有配置錯(cuò)誤
增
任務(wù):新增一個(gè)部門并向這個(gè)部門中新增員工
Test2.java
package com.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.pojo.Dep;
import com.pojo.Emp;
public class Test2 {
public static void main(String[] args) {
/* 使用hibernate之前的準(zhǔn)備 */
Configuration configuration = new Configuration().configure();
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
/* 新建一個(gè)部門并賦值,然后保存到數(shù)據(jù)庫 */
Dep dep = new Dep();
dep.setDid(3);
dep.setDname("財(cái)務(wù)部門");
session.save(dep);
/* 新建員工1,保存到數(shù)據(jù)庫 */
Emp emp1 = new Emp();
emp1.setEid(4);
emp1.setEname("小龍");
emp1.setDep(dep);
session.save(emp1);
/* 新建員工2,保存到數(shù)據(jù)庫 */
Emp emp2 = new Emp();
emp2.setEid(5);
emp2.setEname("小藍(lán)");
emp2.setDep(dep);
session.save(emp2);
/* 提交事務(wù),然后關(guān)閉 */
transaction.commit();
session.close();
}
}
然后可以看到控制臺已經(jīng)打印出了相關(guān)的sql語句,并且沒有異常出現(xiàn),說明執(zhí)行成功

然后查看數(shù)據(jù)庫,相應(yīng)的數(shù)據(jù)已經(jīng)被保存下來了


刪
我們知道在數(shù)據(jù)庫中如果要?jiǎng)h除帶外鍵的表,首先就要?jiǎng)h除子表,不然刪除會出錯(cuò),因?yàn)樽颖磉€在引用父表的時(shí)候,不能直接刪除父表,在Hibernate中也是同樣
Test3.java:
package com.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.pojo.Dep;
import com.pojo.Emp;
public class Test3 {
public static void main(String[] args) {
/* 使用hibernate之前的準(zhǔn)備 */
Configuration configuration = new Configuration().configure();
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
Dep dep = (Dep) session.get(Dep.class, 1);
session.delete(dep);
/* 提交事務(wù),然后關(guān)閉 */
transaction.commit();
session.close();
}
}
可以看到控制臺一片血紅

可以看到直接刪除父表,程序會報(bào)org.hibernate.exception.ConstraintViolationException的異常,在以前的sql語句中,如果要?jiǎng)h除父表,就必須刪除所有外鍵關(guān)聯(lián)父表的元素,才可以刪除父表數(shù)據(jù),下面的例子就是傳統(tǒng)的刪除方式