Hibernate的雙向多對多關聯有兩種配置方法:那我們就來看看兩種方案是如何配置的。 一、創建以各自類為類型的集合來關聯 1.首先我們要在兩個實體類(雇員<Emploee>、工程<Project>)中各自給對方添加一個對方的集合 1.1 雇員實體類 1.2 工程實體類 2.有了實體類之後呢,我們就 ...
Hibernate的雙向多對多關聯有兩種配置方法:那我們就來看看兩種方案是如何配置的。
一、創建以各自類為類型的集合來關聯
1.首先我們要在兩個實體類(雇員<Emploee>、工程<Project>)中各自給對方添加一個對方的集合
1.1 雇員實體類
package cn.manytomany.one;
import java.util.HashSet;
import java.util.Set;
public class Emploee {
//雇員id
private Integer empId;
//工程
private String empName;
//工程的集合
private Set<Project> projects=new HashSet<Project>();
public Set<Project> getProjects() {
return projects;
}
public void setProjects(Set<Project> projects) {
this.projects = projects;
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
}
1.2 工程實體類
package cn.manytomany.one;
import java.util.HashSet;
import java.util.Set;
public class Project {
private Integer proId;
private String proName;
private Set<Emploee> emploees=new HashSet<Emploee>();
public Set<Emploee> getEmploees() {
return emploees;
}
public void setEmploees(Set<Emploee> emploees) {
this.emploees = emploees;
}
public Integer getProId() {
return proId;
}
public void setProId(Integer proId) {
this.proId = proId;
}
public String getProName() {
return proName;
}
public void setProName(String proName) {
this.proName = proName;
}
}
2.有了實體類之後呢,我們就能通過實體的屬性和資料庫的表欄位配置映射關係。
2.1 emploees.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 package="cn.manytomany.one">
<class name="Emploee" table="Emploee">
<id name="empId">
<generator class="sequence">
<param name="sequence">SQU_NUM</param>
</generator>
</id>
<property name="empName"></property>
<set name="projects" table="PROEMP">
<key column="RPROID"></key>
<many-to-many class="Project" column="REMPID">
</many-to-many>
</set>
</class>
</hibernate-mapping>
2.2 projects.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 package="cn.manytomany.one">
<class name="Project" table="PROJECT">
<id name="proId">
<generator class="sequence">
<param name="sequence">SQU_NUM</param>
</generator>
</id>
<property name="proName"></property>
<set name="emploees" table="PROEMP" cascade="save-update">
<key column="REMPID"></key>
<many-to-many class="Emploee" column="RPROID">
</many-to-many>
</set>
</class>
</hibernate-mapping>
2.3 另外還有一個最重要的大配置來引用兩個小配置
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">
oracle.jdbc.OracleDriver
</property>
<property name="connection.url">
jdbc:oracle:thin:@localhost:1521:orcl
</property>
<property name="connection.username">happy</property>
<property name="connection.password">1</property>
<!-- SQL dialect 方言-->
<property name="dialect">
org.hibernate.dialect.Oracle10gDialect
</property>
<!-- Disable the second-level cache 二級緩存-->
<!--<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>-->
<!-- Echo all executed SQL to stdout 是否在控制台顯示sql語句-->
<property name="show_sql">true</property>
<!-- 格式化顯示SQL -->
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- 關聯小配置 -->
<mapping resource="cn/manytomany/doubleanother/emploees.hbm.xml" />
<mapping resource="cn/manytomany/doubleanother/projects.hbm.xml" />
</session-factory>
</hibernate-configuration>
3.最後就是測試類了
package cn.manytomany.one;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class ManyToManyDoubleTest {
/**
* 多對多的雙向關聯測試
*/
public static void main(String[] args) {
Session session = HibernateUtil.currentSession();
Transaction tsc = session.beginTransaction();
//創建雇員
Emploee emp=new Emploee();
emp.setEmpName("田超");
Emploee emp1=new Emploee();
emp1.setEmpName("施強");
//創建工程
Project pro=new Project();
pro.setProName("開發工程");
pro.getEmploees().add(emp);
pro.getEmploees().add(emp1);
try {
session.save(pro);
tsc.commit();
} catch (Exception e) {
// 回滾
tsc.rollback();
}
HibernateUtil.closeSession();
}
}
3.1 最後補充一下工具類,看看就行
package cn.manytomany.one;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
/*
* session工具類
*/
public class HibernateUtil {
private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();
private static Configuration cfg;
private static final SessionFactory sf;
static{
try {
cfg=new Configuration().configure();
sf = cfg.buildSessionFactory();
} catch (Exception e) {
//異常
e.printStackTrace();
throw new ExceptionInInitializerError(e);
}
}
public static Session currentSession(){
Session session=sessionTL.get();
//如果session為null,則打開一個新的session
if (session==null) {
session=sf.openSession();
sessionTL.set(session);
}
return session;
}
public static void closeSession(){
Session session=sessionTL.get();
sessionTL.set(null);
session.close();
}
}
二、創建一個中間的實體類來關聯
1.跟第一個方案差不多,先實現三個實體類,代碼如下:
package cn.manytomany.doubleanother;
import java.util.HashSet;
import java.util.Set;
public class Emploee {
private Integer empId;
private String empName;
private Set<ProEmp> proemp=new HashSet<ProEmp>(); //集合的類型為中間的實體類類型
public Set<ProEmp> getProemp() {
return proemp;
}
public void setProemp(Set<ProEmp> proemp) {
this.proemp = proemp;
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
}
package cn.manytomany.doubleanother;
import java.util.HashSet;
import java.util.Set;
public class Project {
private Integer proId;
private String proName;
//集合的類型依然為中間的實體類類型
private Set<ProEmp> proemp=new HashSet<ProEmp>();
public Set<ProEmp> getProemp() {
return proemp;
}
public void setProemp(Set<ProEmp> proemp) {
this.proemp = proemp;
}
public Integer getProId() {
return proId;
}
public void setProId(Integer proId) {
this.proId = proId;
}
public String getProName() {
return proName;
}
public void setProName(String proName) {
this.proName = proName;
}
}
1.1 補充的中間實體類
package cn.manytomany.doubleanother; public class ProEmp { private Integer id; private Emploee emp; private Project pro; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Emploee getEmp() { return emp; } public void setEmp(Emploee emp) { this.emp = emp; } public Project getPro() { return pro; } public void setPro(Project pro) { this.pro = pro; } }
2. 接下來就是小配置了,跟第一個方案格式幾乎是一樣的,就不過多解釋了,直接來看小配置就行了。
因為我們要用中間實體類來關聯,所以雇員類(Emploee)和工程類(Project)沒有什麼眼添加的,只需按照正常的配置即可。
2.1 emploees.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 package="cn.manytomany.doubleanother">
<class name="Emploee" table="Emploee">
<id name="empId">
<generator class="sequence">
<param name="sequence">SQU_NUM</param>
</generator>
</id>
<property name="empName"></property>
</class>
</hibernate-mapping>
2.2 emploees.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 package="cn.manytomany.doubleanother">
<class name="Project" table="PROJECT">
<id name="proId">
<generator class="sequence">
<param name="sequence">SQU_NUM</param>
</generator>
</id>
<property name="proName"></property>
</class>
</hibernate-mapping>
2.3 關鍵就在於 proemp.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 package="cn.manytomany.doubleanother">
<class name="ProEmp" table="PROEMPNEW">
<id name="id">
<generator class="sequence">
<param name="sequence">SQU_NUM</param>
</generator>
</id>
<many-to-one name="emp" class="Emploee" column="EMPID">
</many-to-one>
<many-to-one name="pro" class="Project" column="PROID">
</many-to-one>
</class>
</hibernate-mapping>
3. 現在就可以進行測試類測試數據了
package cn.manytomany.doubleanother;
import org.hibernate.Session;
import org.hibernate.Transaction;
import cn.manytomany.one.HibernateUtil;
public class ManyToManyDoubleOnlyAnother {
/**
* 多對多雙向關聯---兩個多對一關聯
*/
public static void main(String[] args) {
Session session = HibernateUtil.currentSession();
Transaction tsc = session.beginTransaction();
//創建雇員
Emploee emp=new Emploee();
emp.setEmpName("田超");
//創建工程
Project pro=new Project();
pro.setProName("開發工程");
//中間類
ProEmp proemp=new ProEmp();
proemp.setEmp(emp);
proemp.setPro(pro);
try {
//保存
session.save(emp);
session.save(pro);
session.save(proemp);
tsc.commit();
} catch (Exception e) {
// 回滾
tsc.rollback();
}
HibernateUtil.closeSession();
}
}
好了, Hibernate的多對多雙向關聯的兩種方案已經完成,如果覺得對你們有用的話,記得點個關註啊!!!